5

Unity Container と Dependency Injection について学び始めています。オブジェクト モデルがどのように見えるべきかを理解するのに苦労しています。

私の例では、非常に単純な Employee クラスを作成しました (コンストラクターについては混乱しているため、コンストラクターは省略しました)。

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

この Employee オブジェクトは、データベースから情報を取得する必要があります。依存関係を作成するための shim データベース アダプターを次に示します。

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

理想的には、従業員オブジェクトは、データベースから取得する従業員を知るために「id」パラメーターを取る必要があります。次のような Employee コンストラクタを使用するとします。

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

ParameterOverride を使用する以外に、Unity のリゾルバーで従業員の ID を指定する方法がわかりません。

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

パラメーター名が正しいかどうかを確認するコンパイル時のチェックがないため、これは好きではありません。このような問題は、パターンの適用が間違っていると思わせてくれます。私が誤解していることに誰かが光を当てることができますか?

ありがとう!

4

2 に答える 2

6

依存性注入は、ドメイン モデル / ビジネス オブジェクトで使用することを意図していません。これは主に、サービス、つまりビジネス ロジックの処理に使用されるクラスを解決するためのものです。

したがって、ユーザーは通常、リポジトリまたはその他のデータ アクセス パターンを使用して読み込まれます。

そう:

  1. データ アクセス クラスは DI を使用して挿入されます
  2. データ アクセス クラスはファクトリとして機能し、人物を生成します。

何かのようなもの

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
    }
}
于 2013-02-04T14:45:28.053 に答える
0

このパターンを間違って使用しています。DI とは、主にインターフェイスを介して、依存関係を注入することです。

コードは次のようになります。

インターフェイス

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

と実装

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

次に、次の方法で依存関係を解決できます。

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

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

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

        Console.ReadKey();
    }
}

必要に応じて、IEmployee インターフェイスのさまざまな実装を使用できるようになりました。

于 2013-02-04T14:41:04.497 に答える