工作单元,存储库,注入,使用块

时间:2014-01-25 14:33:29

标签: asp.net-mvc unit-testing ninject unit-of-work

简介

在阅读了多篇关于如何实现工作单元并牢记可测性(单元测试)的文章之后,我可以在以下部分内容中看到以下内容:

  • 接口:IRepository,IUnitOfWork。 IRepository可以(可能是)类似于IRepository<TEntity>的通用。
  • IRepository和IUnitOfWork之间存在耦合。在某些示例中,您可以在IUnitOfWork上看到IRepository中的依赖项。您还会在具体的UnitOfWork
  • 中看到多个IRepository属性
  • 在接近结尾的多个示例中,您可以看到如下用法示例:

    using(var uow = new UnitOfWork()) {
    //some work here, maybe accessing member repositories in uow like:
    //var item = uow.Repository1.GetById(1);
    //item.SomeModifyingOperation();
    uow.Save();
    }
    

问题/观察

  • 这样的用法是否可以测试?它显然取决于UnitOfWork的具体实现。
  • 我们的单元测试是否会出现这样的例子?
  • 如果要进行测试,那么代码会如何变化?我们是否会在ctor(IUnitOfWork uow){this.uow = uow;}之类的构造函数中注入工作单元,然后像这样使用它:this.uow.Save();
  • 如果我们走那条路,那么我们就不能利用使用声明和自动处理uow。我们会手动执行类似uow.Dispose();
  • 的操作
  • 我们(ex:Ninject)可以依赖DI容器来处理每个Web请求(MVC)的处理吗?如果是,我们如何做(Ninject)并且它是设计POV的有效方法吗?
  • 您是否认为一个工作单元可以访问域中的所有存储库(如果UnitOfWork公开存储库),那么我们只有一个具体的IUnitOfWork实现?
  • 将IUnitOfWork保持为仅包含Save()方法签名或让它包含IRepository属性还是像IRepository GetRepository<TEntity>();这样的通用方法签名更好?

参考

1 个答案:

答案 0 :(得分:3)

创建一个通过DI注入的IUnitOfWorkFactory:

public interface IUnitOfWorkFactory
{
    IUnitOfWork Create();
}

public class UnitOfWorkFactory : IUnitOfWorkFactory
{
    public IUnitOfWork Create()
    {
        return new UnitOfWork();
    }
}

然后在您的消费者中注入UnitOfWorkFactory:

public MyController(IUnitOfWorkFactory workFactory)
{
    this.workFactory = workFactory;
}

public ActionResult DoSomething()
{
    using(var uow = workFactory.Create())
    {
        //do work
    }
}

通过这种方式,您可以从两个世界中获得最佳效果。你注入了你的对象 - 有助于测试。并且您可以在需要时自动处理您的UOW。

顺便说一句,这是the DI book值得一读的这些模式的例子。

编辑This chapter from DI book正在谈论一次性对象