2013-02-04 19 views
5

Sto iniziando a conoscere Contenitore Unity e Iniezione di dipendenza. Ho difficoltà a capire come dovrebbe essere il mio modello di oggetto.Unity Container, Risolvi singoli oggetti

Per il mio esempio, ho creato una molto semplice classe Employee (ho omesso il costruttore, perché è quello che sono confuso circa):

public class Employee 
{ 
    private int _id; 
    private string _name; 
    private DateTime _birthDate; 

    public int Id 
    { 
     get { return _id; } 
    } 

    public string Name 
    { 
     get { return _name; } 
    } 

    public DateTime BirthDate 
    { 
     get { return _birthDate; } 
    } 
} 

Questo oggetto Employee dovrebbe ottenere le informazioni da un database . Qui è un adattatore di database di shim, solo per sviluppare una dipendenza:

public class DataAdapter 
{ 
    public DbParameter NewParameter(string name, object value) 
    { 
     return new OracleParameter(name, value); 
    } 

    public DataRow ExecuteDataRow(string command, CommandType commandType, List<DbParameter> parameters) 
    { 
     DataTable dt = new DataTable(); 

     dt.Columns.Add(new DataColumn("ID")); 
     dt.Columns.Add(new DataColumn("NAME")); 
     dt.Columns.Add(new DataColumn("BIRTH_DATE")); 

     DataRow dr = dt.NewRow(); 

     dr["ID"] = new Random().Next(); 
     dr["NAME"] = "John Smith"; 
     dr["BIRTH_DATE"] = DateTime.Now; 

     return dr; 
    } 
} 

Idealmente, l'oggetto dipendente deve prendere un parametro "id", al fine di conoscere quali dei dipendenti per recuperare dal database. Diciamo che usiamo un costruttore di Employee che assomiglia a questo:

public Employee(int id, DataAdapter dataAdapter) 
{ 
    List<DbParameter> parameters = new List<DbParameter>(); 

    parameters.Add(dataAdapter.NewParameter("ID", id)); 

    DataRow dr = dataAdapter.ExecuteDataRow("GetEmployee", CommandType.StoredProcedure, parameters); 

    if (dr == null) 
     throw new EmployeeNotFoundException(); 

    _id = id; 
    _name = Convert.ToString(dr["NAME"]); 
    _birthDate = Convert.ToDateTime(dr["BIRTH_DATE"]); 

    _id = employeeData.Id; 
    _name = employeeData.Name; 
    _birthDate = employeeData.BirthDate; 
} 

Non sono sicuro di come specificare id del Dipendente con resolver di Unity, tranne usando ParameterOverride:

class Program 
{ 
    static void Main(string[] args) 
    { 
     UnityContainer container = new UnityContainer(); 

     container.RegisterType(typeof(EmployeeData)); 

     Employee emp = container.Resolve<Employee>(new ParameterOverride("id", 45)); 

     Console.WriteLine(emp.Id); 
     Console.WriteLine(emp.Name); 
     Console.WriteLine(emp.BirthDate); 
     Console.ReadKey(); 
    } 
} 

non mi piace questo perché non c'è un controllo in fase di compilazione per vedere se il nome del parametro è corretto. Problemi come questo mi fanno pensare che sto applicando il modello in modo errato. Qualcuno può far luce su ciò che sto fraintendendo?

Grazie!

risposta

6

Iniezione di dipendenza non è destinato a essere utilizzato su modelli di dominio/oggetti business. È principalmente per risolvere i servizi, ad esempio le classi utilizzate per elaborare la logica aziendale.

Quindi le persone vengono normalmente caricate utilizzando un repository o qualsiasi altro modello di accesso ai dati.

Quindi:

  1. La vostra classe di accesso ai dati viene iniettato utilizzando
  2. I suoi atti di classe di accesso ai dati DI come una fabbrica e genera la persona.

qualcosa come

public class PersonRepository 
{ 
    public PersonRepository(IDbConnection iGetInjected) 
    { 
    } 

    public Person Get(int id) 
    { 
     // I create and return a person 
     // using the connection to generate and execute a command 
    } 
} 
+0

Ah, okay, stavo cercando di evitare l'uso del pattern Factory perché pensavo che fossero in qualche modo mutuamente esclusivi, ma immagino che siano complementari dopotutto. Grazie per l'aiuto! –

0

Si sta utilizzando questo modello in modo errato. DI riguarda l'iniezione di dipendenze, principalmente attraverso interfacce.

Il codice dovrebbe essere simile a questa:

l'interfaccia

public interface IEmployee 
{ 
    int Id { get; set;} 
    string name { get; set;} 
    DateTime BirthDate { get; set; } 
} 

e l'attuazione

public class Employee : IEmployee 
{ 
    public int Id { get; set;} 
    public string name { get; set;} 
    public DateTime BirthDate { get; set; } 
} 

allora si può risolvere la dipendenza attraverso:

class Program 
{ 
    static void Main(string[] args) 
    { 
     UnityContainer container = new UnityContainer(); 

     container.RegisterType(typeof(IEmployee), typeof(Employee)); 

     IEmployee emp = container.Resolve<IEmployee>(); 

     Console.ReadKey(); 
    } 
} 

No w è possibile utilizzare diverse implementazioni dell'interfaccia IEmployee in base alle proprie esigenze.

+0

Non ti ho downvote, ma ho il sospetto che fosse perché non hai spiegare come risolvere la parte "parametro del costruttore id" della mia domanda. Grazie comunque per la tua risposta! –

Problemi correlati