2013-02-04 22 views
5

Ich fange an, etwas über den Unity Container und die Dependency Injection zu lernen. Ich habe Schwierigkeiten zu verstehen, wie mein Objektmodell aussehen sollte.Unity Container, einzelne Objekte lösen

Für mein Beispiel habe ich eine wirklich einfache Klasse Employee (I die Constructor weggelassen habe, denn das ist, was ich bin verwirrt):

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; } 
    } 
} 

Dieser Employee-Objekt sollte seine Informationen aus einer Datenbank erhalten . Hier ist ein Shimdatenbank Adapter, nur eine Abhängigkeit zu entwickeln:

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; 
    } 
} 

Idealerweise der Mitarbeiter Objekt sollte ein „id“ Parameter nehmen, um zu wissen, welche Mitarbeiter aus der Datenbank abgerufen werden. Lassen Sie uns sagen, dass wir einen Mitarbeiter Konstruktor verwenden, der wie folgt aussieht:

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; 
} 

Ich bin nicht sicher, wie die Mitarbeiter-ID mit Resolver Unity angeben außer ParameterOverride mit:

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(); 
    } 
} 

Ich mag es nicht Dies liegt daran, dass keine Überprüfung der Kompilierungszeit stattfindet, um festzustellen, ob der Parametername korrekt ist. Probleme wie diese lassen mich denken, dass ich das Muster falsch anwende. Kann jemand etwas Licht auf das werfen, was ich falsch verstehe?

Danke!

Antwort

6

Die Abhängigkeitsinjektion ist nicht für Domänenmodelle/Geschäftsobjekte vorgesehen. Es dient hauptsächlich zur Auflösung von Diensten, d. H. Klassen, die zur Verarbeitung von Geschäftslogik verwendet werden.

Daher werden Ihre Personen normalerweise mit einem Repository oder einem anderen Datenzugriffsmuster geladen.

So:

  1. Ihre Datenzugriffsklasse verwendet injiziert DI
  2. Ihre Datenzugriffsklasse fungiert als Fabrik und erzeugt die Person.

so etwas wie

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, ich habe versucht, das Factory-Muster zu vermeiden, weil ich dachte, dass sie sich gegenseitig ausschließen würden, aber ich denke, dass sie sich schließlich ergänzen. Danke für Ihre Hilfe! –

0

Sie verwenden dieses Muster falsch. Bei DI geht es um die Injektion von Abhängigkeiten, hauptsächlich über Schnittstellen.

Der Code sollte wie folgt aussehen:

die Schnittstelle

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

und Umsetzung

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

dann können Sie die Abhängigkeit durch beheben:

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

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

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

     Console.ReadKey(); 
    } 
} 

Nein w Sie können je nach Bedarf verschiedene Implementierungen der IEmployee-Schnittstelle verwenden.

+0

Ich habe Sie nicht downvote, aber ich vermute, es war, weil Sie nicht erklären, wie der „id Konstruktorparameter“ Teil meiner Frage zu lösen. Danke für Ihre Antwort! –

Verwandte Themen