【问题标题】:Are you supposed to wrap Unit of Work?你应该包装工作单元吗?
【发布时间】:2014-02-25 16:43:56
【问题描述】:

我一直在尝试对整个 EF/存储库/工作单元架构进行自我教育——进展缓慢。

无论如何,我已经设法创建了一些使用接口的存储库和一个工作单元。 (我花了一个小时才让它在没有接口的情况下完美运行)。

对..这个问题。在这里包装工作单元有什么意义吗?

private readonly IUnitOfWork _unitOfWork;

public ActionResult Index()
{
    var all = _unitOfWork.CampaignRepository.All().ToList();
    return View(all);            
}

或者

public ActionResult Index()
{
    using (var uow = _unitOfWork)
    {
        all = uow.CampaignRepository.All().ToList();
        return View(all);
    }
}

另外——在控制器中实例化

public CampaignController(MarketingContext context)
{
    _unitOfWork = new UnitOfWork(context);
}

这是否意味着它在控制器中始终可用?还是仅在专门调用工作单元时?

抱歉有任何天真,但我已经阅读了很多不同的做任何事情的方法!

【问题讨论】:

  • 我通常通过控制器构造函数注入依赖,这使得代码更具可测试性。我还使用了一个 IoC 容器,它为依赖项抽象了生命周期问题,因此无需担心处理工作单元。
  • 如果你使用ef,它已经包含了uof和repository。
  • @chenZ 我已经读到 EF 已经这样做了,但是我希望能够在我的项目和存储库上运行单元测试,并且 UoW 允许这样做吗?

标签: c# asp.net-mvc entity-framework


【解决方案1】:

首先,由于您使用的是实体框架,因此您不需要实现 UnitOfWork 模式,因为 EF 默认支持 UOF。(EF 的 SaveChanges 支持 UOF) 现在,如果您想实现 UnitOfWork,请不要使用 ToList() 获取存储库的所有实体,因为您无需在调用控制器时对数据进行操作(这是一个性能问题),这样会更好UnotOfWork 和 Repository 模式的实现看this 文章。

【讨论】:

    【解决方案2】:

    我永远不会将字段包装在 using 语句中,因为可以想象该字段可能在其他地方的范围内,但已经被释放。通常你应该在 using 子句中实例化一次性对象:

       using(var scope = new TransactionScope())
       {
          //etc
       }
    

    覆盖控制器中的 Dispose 方法并在您的 UOW 上调用 dispose:

       protected override void Dispose(bool disposing)
       {
           if (disposing)
               _unitOfWork.Dispose();
            base.Dispose(disposing);
       }
    

    或者您可以按照 elolos 评论中的建议在 IoC 容器中指定范围

    【讨论】:

      猜你喜欢
      • 2019-11-11
      • 1970-01-01
      • 2014-10-01
      • 1970-01-01
      • 2019-06-04
      • 2012-12-06
      • 1970-01-01
      • 1970-01-01
      • 2012-08-03
      相关资源
      最近更新 更多