我一直在阅读,现在已经看到了工作单元模式的两种不同实现。第一种模式使存储库与工作单元对话为域对象。
另一个实现使服务层将域对象注册为已修改:
我想我的问题是,每个的好处/缺点是什么?我知道在没有为存储库/映射器/等提供一些实现代码的情况下有很多答案......但总的来说,谁/什么应该真正负责“新建”UoW然后使用它?
我的想法是,如果您让Repository处理它,它应该作为存储库的可注入接口提供,因此相同的UoW可以跨越多个存储库(也就是多个域对象)......
如果服务层处理它,那么每个服务层调用只有一个UoW实现(例如,ServiceLayer.AddCustomer(客户)),你就会“陷入困境”。
在网络世界中,我看不到为不同的域对象调用多个服务层......但也许在非网络世界中我可以。
我想最终必须调用“commit()”,因此最有意义的是将其绑定到服务层。
谢谢, 麦克
答案 0 :(得分:1)
即使在第一个实例中,您的UnitOfWork很可能是单个(每个线程),因此即使CustomerRepository和OtherBoilerplateExampleRepository都在调用提交之前访问UnitOfWork,提交仍将使用所有更改库。
话虽如此,我认为第一种模式是更清洁的方式。使用第二种方式,您说CustomerService必须同时操作业务对象和使用UnitOfWork注册更改。这有点违反了关注点。此外,这些示例中未显示,但Repository模式也提供了缓存数据对象的位置。
就注入依赖关系而言,我认为而不是使UoW成为可注入的接口,使Mapper模式(您在第二个示例中看到但可能在第一个示例中暗示)注入是更合适的选择。无论您使用的是SQL DB,XML文件等,UoW事务管理功能都应该保持不变。
答案 1 :(得分:1)
将UoW暴露给客户端通常比使用存储库实现更强大的抽象,因为语义是基于状态的,而不是显式的“加载/保存/删除”操作。另一方面,显性允许客户通过使用规范等更好地控制线上真正发生的事情。
IMO没有“正确”的方法,选择最合适的模式实际上取决于应用程序的数据流和持久层约束。
一些想法 -
存储库通常管理单个聚合门根,而UoW可以覆盖多个。
理想情况下,UoW应该是持久性不可知的(因为它主要处理对象状态,例如更改跟踪)。您的映射器显然将根据您的存储实施进行定制。但其他存储问题/责任在哪里得到解决?存储库通常就是答案。
存储库模式可以更容易地使用专门的语义扩展存储解决方案(通过添加新方法),或者调整内部实现(例如在某些场景中调用sproc而不是动态代码)
对于具有直接和同质存储要求的应用程序,直接暴露UoW可能是一个更简单的模型。对于更复杂的环境(例如动态SQL和sprocs的混合使用,遗留模式等),然后Repository更易于维护和扩展,代价是使用起来有点限制。
这是我的头脑,希望它有帮助...