如何让工作单元与服务模式一起运行?

时间:2017-06-19 11:46:39

标签: c# asp.net entity-framework repository-pattern

我正在使用工作单元模式,正如本article中所述。文章解释说每个服务都应该注入一个UnitOfWork:

private readonly IUnitOfWork _unitOfWork;

此外,服务必须具有公共方法来提交工作单元操作:

public void Save()
{
   _unitOfWork.Commit();
}

Save方法只能由调用该服务的(webapi)控制器调用。

但这是我的担忧:

1)控制器可以使用数据库更新调用多个服务,在这种情况下,它应该为每个服务调用Save()?那么如果需要回滚呢?

像:

[HttpGet]
public IHttpActionResult UpdateArchive()
{
   _service1.DoUpdate();
   _service1.Save();
   _service2.DoUpdate();
   _service2.Save();
}

如果service2.Save失败怎么办?

2)如果服务调用另一个服务,控制器将如何知道要调用哪个Save?

我对这个工作单元感到有点困惑。

1 个答案:

答案 0 :(得分:2)

  

并且在这种情况下应该为每个服务调用Save()

这取决于服务是否共享相同的工作单元。如果是,请在其中任何一个上调用{ "PoloniexAbbreviations" : [ "LGD", "PTOY", "PTOY" ], "PoloniexCurrencyPairs" : [ "ETH_LGD", "BTC_PTOY", "ETH_PTOY" ], "PoloniexNames" : [ "Legends", "Patientory", "Patientory" ] } ,它会将操作委托给同一个UoW。

  

如果需要回滚那么

由于没有交易,您应该如何回滚?

另一方面,在业务流程上引入显式事务使得回滚更改变得微不足道:

Save

try { using ( TransactionScope scope = new TransactionScope() ) { _service1.DoUpdate(); _service1.Save(); _service2.DoUpdate(); _service2.Save(); scope.Complete(); } } catch { // rollback occurs since the transaction was not completed } 非常方便,因为它应该正确处理共享UoW上的事务和注入不同服务的多个不同UoW上的事务。

  

如果service2.Save失败怎么办?

你回滚了这个交易,这里几乎没有任何其他选择。

无论如何,repositories/uow over EF are disputable。您的部分问题是多个服务共享UoW的相同实例,因此基本上与您调用的TransactionScope无关紧要,他们都在同一个Save上调用SaveChanges

我的意见(尽管这里应该避免意见)是你可能会从服务中删除DbContext并在业务流程结束时坚持使用数据库上下文中的单个Save。这样可以使意图更清晰 - 服务是改变UoW的内部状态,但是持续更改的责任在控制器上。