将存储库依赖项注入工作单元

时间:2013-01-17 09:40:31

标签: c# dependency-injection repository-pattern unit-of-work

我正在尝试在我的asp.net MVC项目中使用Repository和Unit of Work模式,但是我很难弄清楚如何将Repository依赖项传递给Unit of Work。工作单元的一般标准结构如下:

public class UnitOfWork : IUnitOfWork
 {
        private ICustomerRepository _customerRepository;

        public ICustomerRepository CustomerRepository
        {
            get
            {
                if (this._customerRepository == null)
                {
                    this._customerRepository = new CustomerRepository(someContext);
                }
                return _customerRepository;
            }
        }
}

具体来说,令我困惑的是这一行:

this._customerRepository = new CustomerRepository(someContext);

通过定义存储库的接口,随着时间的推移和业务需求的变化,是不是能够将存储库依赖关系注入UoW?如果是这样,为什么我在网上看到的几乎所有实现都是如此?在这个实现中,我们如何将ICustomerRepository的新实例传递给UoW?当然,我们还需要更改UoW中的代码,而不是违反开放式原则吗?我如何将存储库注入我的UoW?

我环顾四周,this question似乎曾经被问过,但我仍然很难理解建议的解决方案(门面服务)。

1 个答案:

答案 0 :(得分:2)

获取CustomerRepository实例有两种常用方法。 第一种方法称为构造函数注入,它是构造函数中的一个简单参数,例如

public class UnitOfWork : IUnitOfWork
{
    public UnitOfWork(ICustomerRepository repository)
    {
        _customerRepository = repository;
    }

    private ICustomerRepository _customerRepository;

    public ICustomerRepository CustomerRepository
    {
        get
        {
            if (this._customerRepository == null)
            {
                throw new ArgumentException("Missing repository");
            }
            return _customerRepository;
        }
    }
}

第二种也是更灵活的方法是使用像Structuremap,Unity,Ninject等IoC框架。

以下是Structuremap的示例:

public class UnitOfWork : IUnitOfWork
{
    private ICustomerRepository _customerRepository;

    public ICustomerRepository CustomerRepository
    {
        get
        {
            if (this._customerRepository == null)
            {
                _customerRepository = ObjectFactory.GetInstance<ICustomerRepository>();
            }
            return _customerRepository;
        }
    }
}

另外你需要一个configuraiton类来告诉Structuremap要实例化哪个类,它可能看起来像这样:

public static class RepositoryRegistry
{
    internal static void DefaultConfiguration(Registry registry)
    {
       registry.For<ICustomerRepository>().Use<CustomerRepository>();
    }
}