如何通过依赖注入创建List <customer>?</customer>

时间:2013-12-07 08:24:36

标签: c# dependencies unity-container code-injection

我的目标是从数据库加载数据并返回List。以下是我目前的代码:

    public class CustomerRepository : ICustomerRepository
     {

        public IEnumerable<Customer> GetAll()
        {
            List<Customer> Customers = new List<Customer>();

            DataTable dtResult; 
            using (
        DbCommand cmd = TheDB.GetStoredProcCommand("spSelectAllCustomer"))
            {
                dtResult = TheDB.ExecuteDataSet(cmd).Tables[0];
            }


            Customers.AddRange( 
               from DataRow row in dtResult.Rows

               //*** How can I inject a new Customer instance in here?

               select new Customer() {
                          Name = row[0].ToString(), 
                          Email = row[1].ToString()
                     });

            return Customers;
        }
    }

我不知道如何用注射替换新客户。 我应该使用container.Resolve吗? 是container.Resolve一个服务定位器,一个反模式?

感谢。

1 个答案:

答案 0 :(得分:0)

使用Factory Pattern创建您的实例。我会重构您的代码,如下所示。

介绍一个最近调用Repo和您创建的工厂的服务。该服务,我称为ICustomerProcessor。 (ICusomerService可能不是这里的正确选择)。使用您的IUnityContainer,此处理器,您的工厂和存储库是依赖注入的。有些人称之为Facade

public interface ICustomerProcessor {
    IEnumerable<Customer> GetAll();
}

此服务的实现只需要调用Repository来获取数据,然后调用工厂来创建实体。

public class CustomerProcessor : ICustomerProcessor {
    private readonly ICustomerFactory _customerFactory;
    private readonly ICustomerRepository _customerRepository;

    public CustomerProcessor(ICustomerRepository customerRepository, ICustomerFactory customerFactory)
    {
        _customerRepository = customerRepository;
        _customerFactory = customerFactory;
    }

    public IEnumerable<Customer> GetAll()
    {
        var data = _customerRepository.GetDataTable();
        return _customerFactory.CreateCustomers(data);
    }
}  

repository仅表示您的数据库,它只是抽象您的数据库调用。

public class CustomerRepository : ICustomerRepository
{
    private readonly IDatabaseContext _database;

    public CustomerRepository(IDatabaseContext database) {
        _database = database;
    }


    public DataTable GetDataTable() {
        DataTable dtResult;
        using (DbCommand cmd = _database.GetStoredProcCommand("spSelectAllCustomer"))
        {
            dtResult = _database.ExecuteDataSet(cmd).Tables[0];
        }

        return dtResult;
    }
}

请注意,IDatabaseContext不需要Dependency Injected,它可以只是您调用db的静态上下文。但关键的想法是你的Repository封装了数据库操作,但没有别的。

关于Container.Resolve: 您不需要这个,因为您的服务是通过contructore注入注入的。您的域对象不应该是依赖注入。它们只是实体。

关于服务定位器。 它不是service locator反patten,它是人们使用它的方式使它成为反模式。在您的情况下,绝对不需要在上下文中有服务定位器。但在某些情况下,当您无法获得某些依赖项时,您可以使用服务定位器。但这些案件很少见。

更新:

实施 ICustomerFactory

public interface ICustomerFactory {
    IEnumerable<Customer> CreateCustomers(DataTable data);
}

public class CustomerFactory
{
    public IEnumerable<Customer> CreateCustomers(DataTable data)
    {
         return (from DataRow row in data.Rows
             select new Customer
             {
                 Name = row[0].ToString(), Email = row[1].ToString()
             }).ToList();
    }
}