C# Unity容器,解析单个对象

C# Unity容器,解析单个对象,c#,unity-container,C#,Unity Container,我开始学习Unity容器和依赖注入。我很难理解我的对象模型应该是什么样子 在我的示例中,我创建了一个非常简单的Employee类(我省略了构造函数,因为这正是我所困惑的): 此Employee对象应从数据库获取其信息。下面是一个shim数据库适配器,用于开发依赖关系: public class DataAdapter { public DbParameter NewParameter(string name, object value) { return new

我开始学习Unity容器和依赖注入。我很难理解我的对象模型应该是什么样子

在我的示例中,我创建了一个非常简单的Employee类(我省略了构造函数,因为这正是我所困惑的):

此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;
    }
}
公共类数据适配器
{
public DbParameter NewParameter(字符串名称、对象值)
{
返回新的OracleParameter(名称、值);
}
public DataRow ExecuteDataRow(字符串命令、CommandType CommandType、列表参数)
{
DataTable dt=新的DataTable();
添加(新数据列(“ID”);
添加(新数据列(“名称”));
添加(新数据列(“出生日期”);
DataRow dr=dt.NewRow();
dr[“ID”]=new Random().Next();
博士[“姓名”]=“约翰·史密斯”;
dr[“出生日期”]=DateTime.Now;
返回dr;
}
}
理想情况下,employee对象应该采用“id”参数,以便知道从数据库中检索哪个员工。假设我们使用的员工构造函数如下所示:

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;
}
public Employee(int-id,DataAdapter-DataAdapter)
{
列表参数=新列表();
Add(dataAdapter.NewParameter(“ID”,ID));
DataRow dr=dataAdapter.ExecuteDataRow(“GetEmployee”,CommandType.StoredProcess,参数);
如果(dr==null)
抛出新EmployeeNotFoundException();
_id=id;
_name=Convert.ToString(dr[“name”]);
_birthDate=Convert.ToDateTime(dr[“birthDate”]);
_id=employeeData.id;
_name=employeeData.name;
_生日=雇员数据。生日;
}
我不知道如何使用Unity的解析器指定员工id,除非使用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();
    }
}
类程序
{
静态void Main(字符串[]参数)
{
UnityContainer容器=新的UnityContainer();
container.RegisterType(typeof(EmployeeData));
Employee emp=container.Resolve(新参数override(“id”,45));
控制台写入线(emp.Id);
控制台写入线(emp.Name);
控制台写入线(皇帝生日);
Console.ReadKey();
}
}
我不喜欢这样,因为没有编译时检查参数名是否正确。像这样的问题让我觉得我应用了错误的模式。有人能解释一下我的误解吗


谢谢

您不正确地使用了此模式。DI主要是通过接口注入依赖项

您的代码应该如下所示:

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

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();
    }
}
类程序
{
静态void Main(字符串[]参数)
{
UnityContainer容器=新的UnityContainer();
container.RegisterType(typeof(ieemployee),typeof(Employee));
IEEmployee emp=container.Resolve();
Console.ReadKey();
}
}

现在,您可以根据需要使用不同的IEEmployee接口实现。

依赖项注入不适用于域模型/业务对象。它主要用于解析服务,即用于处理业务逻辑的类

因此,您的人员通常使用存储库或任何其他数据访问模式加载

因此:

  • 您的数据访问类是使用DI注入的
  • 数据访问类充当工厂并生成person
  • 差不多

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

    啊,好吧,我试图避免使用工厂模式,因为我认为它们有点相互排斥,但我想它们毕竟是互补的。谢谢你的帮助!我没有投你反对票,但我怀疑是因为你没有解释如何解决我问题中的“id构造函数参数”部分。谢谢你的回复!