Ninject EF4,存储库和工作单元

时间:2013-03-15 14:19:16

标签: .net dependency-injection ninject repository-pattern

我的解决方案中有几个项目访问相同的数据,因此我稍后在一个单独的项目中实现数据访问。目前我正在使用EF4,一个通用存储库和一个工作单元模式。我设计了我的数据访问以支持依赖注入,我想使用Ninject。这是我到目前为止的样本

public class Account 
{
    public int Id { get; set; }
    public Guid WebId { get; set; }
    public string Firstname { get; set; }
    public string Lastname { get; set; }
    public string Email { get; set; }
    public string Address { get; set; }
    public string Mobile { get; set; }

}

public interface IRepository<T>
{
    IEnumerable<T> Get(Expression<Func<T, bool>> filter, Func<IQueryable<T>);
    T GetById(int id);
    void Update(T dinner);
    void Insert(T dinner);
    void Delete(int id);
    void Save();
}

我还有一个存储库实现,我不会在这里发布空间。

我的UnitOfWork看起来像这样

public class UnitOfWork
{        
    private Repository<Account> _accountRepository;
    public IRepository<Account> AccountRepository
    {
        get
        {
            if (this._accountRepository == null)
            {
                _accountRepository = new Repository<Account>();
            }
            return _accountRepository;
        }
    }       
}

我如何以及在何处设置ninject以自动解析我的存储库,以便我可以使用该接口而不需要在我的工作单元中实例化它。这是正确的做法,还是我认为DI的问题都错了?以下是我认为我希望我的工作单元看起来像

public class UnitOfWork
{
    IKernel _kernel;

    public UnitOfWork()
    {
        _kernel = new StandardKernel();
    }

    private IRepository<Account> _accountRepository;

    public IRepository<Account> AccountRepository
    {
        get
        {
            if (this._accountRepository == null)
            {
                _accountRepository = _kernel.Get<IRepository<Account>>();;
            }
            return _accountRepository;
        }
    }

}

1 个答案:

答案 0 :(得分:0)

依赖注入倾向于使用称为组合根的概念。这是您的应用程序中的一个位置,其中包含应用程序的对象图的组成。

您本身不在库中使用依赖项注入容器。您的库可能包含可以注入的对象,但它往往是基于应用程序的工具,而不是基于库的工具。

这意味着如果您只创建一个库,则不会在其中使用依赖项注入容器,也不会在其中配置容器。相反,您将创建库以使用应用程序中的依赖项注入。在您的情况下,您只需设计您的存储库,工作单元等,以通过构造函数注入接受其依赖项。然后,在使用库的应用程序中,您将使用DI容器(例如Ninject)来配置对象的创建方式。

这做了很多事情。首先,它允许应用程序控制对象的创建方式。例如,如果您在Web应用程序中使用库,则可以将其配置为创建存储库的实例,该实例将在一个请求的生命周期中存在。如果您的库执行了此操作,那么您将无法在应用程序级别对此进行控制。

其次,如果您在库中使用DI容器,那么您的应用程序中还需要一个DI容器,因此最终会有两个DI容器,这可能会导致各种冲突。在大多数情况下,应用程序中应该只有一个DI容器。

最后,你犯了一个经典的新手错误。您正在将DI容器与DI本身的概念混淆。 DI是您设计类的方式,特别是它们如何接受来自对象外部的依赖关系。

DI容器是用于实现DI的工具,而不是DI本身。

TL; DR

不要设计库以拥有自己的DI容器。