Design patterns 如何使用依赖项注入和存储库处理工作单元

Design patterns 如何使用依赖项注入和存储库处理工作单元,design-patterns,dependency-injection,mvp,unit-of-work,Design Patterns,Dependency Injection,Mvp,Unit Of Work,我继承了一些代码,其中有一个UnitOfWorkFactory,它在每个存储库方法中创建一个工作单元。问题是单个存储库方法很少是完整的工作单元,因此如果在(比如)OrderService.PlaceOrder中出现问题,它不能回滚/放弃该工作单元,因为它不是一个单元 看看代码,我认为工作单元应该转移到服务类或演示者中。然后我遇到的问题是如何将其传递给服务或存储库?演示者将获得一个服务实例,服务将获得一个存储库实例 我可以创建工作单元,并让它注入服务、存储库和演示者的构造函数,但它将超越单个工作单

我继承了一些代码,其中有一个UnitOfWorkFactory,它在每个存储库方法中创建一个工作单元。问题是单个存储库方法很少是完整的工作单元,因此如果在(比如)OrderService.PlaceOrder中出现问题,它不能回滚/放弃该工作单元,因为它不是一个单元

看看代码,我认为工作单元应该转移到服务类或演示者中。然后我遇到的问题是如何将其传递给服务或存储库?演示者将获得一个服务实例,服务将获得一个存储库实例

我可以创建工作单元,并让它注入服务、存储库和演示者的构造函数,但它将超越单个工作单元。这是一个桌面应用程序,因此演示者及其传递的任何服务都可以在多个工作单元中处于活动状态

我认为传递工作单元的唯一方法是将其作为参数添加到所有服务/存储库方法中。我忍不住想,一定有比这更好的办法,我是不是错过了什么

代码如下所示:

存储库:

classorderrepository
{
公共工厂单位工厂单位;
公共订单存储库(UnitOfWorkFactory UnitOfWorkFactory)
{
UnitOfWorkFactory=UnitOfWorkFactory;
}
公共作废保存(订单)
{
使用(var uow=UnitOfWorkFactory.Create())
{
//保存订单
提交();
}
}
}
服务:

classorderservice
{
受保护的IOrderRepository OrderRepository;
受保护的IPProductService产品服务;
public OrderService(IORDRepository orderRepository、IPProductRepository productService)
{
OrderRepository=OrderRepository;
ProductService=ProductService;
}
公共无效订单(订单)
{
foreach(order.Items中的变量项)
{
如果(!ProductService.IsInstock(item.Product,item.Quantity))
抛出新ProductOutOfStockException(产品);
ProductService.MarkForDispatch(item.Product,item.Quantity);
}
OrderRepository.Save(订单);
}
公共无效取消订单(订单)
{
ProductService.UnmarkForDispatch(item.Product,item.Quantity);
order.IsCanceled=true;
OrderRepository.Save(订单);
}
}
演示者:

类OrderPresenter
{
受保护的IOrderView OrderView;
受保护的IOrderService OrderService;
public OrderPresenter(IOrderView orderView、IOrderService orderService)
{
OrderView=OrderView;
OrderService=OrderService;
}
公共秩序
{
OrderService.PlaceOrder(订单);
}
公共法庭法官()
{
OrderService.CancelOrder(订单);
}
}

我没有一个简短的答案。你可以在我之前写的关于这个主题的博客文章中查看完整答案
(如果你读了这篇文章,请告诉我你的想法)

我决定最终使用工厂,并通过该工作单元。然后,工厂使用传递的UOW创建所有其他内容

这就是如果你最终做了什么:

存储库:

公共类存储库:IRepoository
{
i工作单元工作单元;
公共存储库(IUnitOfWork uow)
{
工作单位=uow;
}
公共void SomeOtherMethod(int-id)
{
//做点什么
}
}
服务:

公共类服务:iSeries
{
i工作单元工作单元;
iRepository存储库;
公共服务(IUnitOfWork uow、iRepository存储库)
{
工作单位=uow;
存储库=存储库;
}
公共方法(int-id)
{
Repository.SomeOtherMethod(id);
//做其他事情
}
}
工厂:

公共类IUnitOfWorkFactory
{
i工作单元创建();
}
公营部门
{
iSeries设备创建(IUnitOfWork uow);
}
IServiceFactory.Create
方法创建服务和服务所依赖的存储库,并为它们提供传递的工作单元

预设器:

公共类演示者
{
受保护的工厂单位工厂单位;
受保护的IServiceFactory服务工厂;
公共演示者(IUnitOfWorkFactory unitOfWorkFactory、IServiceFactory服务工厂)
{
UnitOfWorkFactory=UnitOfWorkFactory;
服务工厂=服务工厂;
}
公共无效剂量测定法()
{
//从工厂得到一个新的UOW
使用(var uow=unitOfWorkFactory.Create())
{
//然后通过ServiceFactory使用新UOW创建服务和存储库
var service=serviceFactory.Create(uow);
服务方法(20);
提交();
}
}
}

您使用的是胖客户端还是瘦客户端(如HTTP)?@jgauffin这是一个胖客户端。这是一个桌面应用程序,在本地处理所有业务规则。这看起来是一个不错的解决方案。我最终的做法略有不同(见下文),但我会将此标记为答案,因为它也会解决问题。这看起来是一个很好的解决方案,但您需要为每项服务创建一个工厂。如果我最后在我的帖子中添加了你的一些想法,我会记得给你点表扬。是的,这是这种方法的一个缺点。对我来说,这不是一个问题,因为代码使用一个库来进行依赖项注入,所以我可以创建一个接受UOW的通用工厂接口,它将自动创建实现。您也可以手动创建一个通用工厂来轻松地完成这项工作。