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

本文关键字:工作 单元 注入 存储 依赖 | 更新日期: 2023-09-27 17:53:46

我试图在我的asp.net MVC项目中采用存储库和工作单元模式,但是我很难弄清楚如何将存储库依赖项传递给工作单元。工作单元的一般标准结构似乎如下:

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注入存储库?

我看了一下SO,这个问题似乎以前已经问过了,但是我仍然很难理解提议的解决方案(facade服务)。

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

有两种常见的方法来获取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;
        }
    }
}

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

下面是Structuremap的一个例子:
public class UnitOfWork : IUnitOfWork
{
    private ICustomerRepository _customerRepository;
    public ICustomerRepository CustomerRepository
    {
        get
        {
            if (this._customerRepository == null)
            {
                _customerRepository = ObjectFactory.GetInstance<ICustomerRepository>();
            }
            return _customerRepository;
        }
    }
}

另外,你需要一个配置类来告诉Structuremap要实例化哪个类,它可以简单地看起来像这样:

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