我试图找出一个很好的做法来构建/分层和工作单元。
我们使用C#,编写MVC前端应用程序。目前的正常结构是:
MVC 服务/域层 存储库层 EF6
MVC只会调用该服务,(这里没有逻辑)。该服务包含所有域逻辑。存储库使用EF6处理数据访问。将存储库层置于EF之上的主要三个原因是:
1)单一责任(SRP),该服务处理业务关心的内容,存储库处理获取和保存数据。使用存储库意味着它们不会混合到同一个方法中。 2)测试,它使存储库更容易。 (我知道你现在可以模拟dbcontext,老实说还没有尝试过这种方法)。 3)从域中抽象出EF,因为它并不真正关心它,(尽管这是一个非常微弱的争论)。
我们将为系统的不同部分提供单独的服务和存储库,例如:
1)CustomerService 2)InvoiceService 3)OrdersService
每个存储库都有自己的实例(即没有通用存储库),允许我们准确编辑我们想要的内容并创建返回我们想要的查询,而不是获取非常大的对象或进行大量的单独调用(并避免必须从域中传递大量的包含状态。)
这种结构通常很有效。我们发现服务层类有时会非常大(最终破坏SRP)。认为我们应该最终将它们分成子服务。如果是CustomerService,可能会成为CustomerQueryService和CustomerAdminService。我们还发现这个结构对存储库有帮助,因为我们的一些查询最终变得非常大,将数据转换为正确的格式,而不是拉出比所需数据更多的数据。
当我想要使用交易时,它对我而言就失败了。如果我将每个存储库转换为一个工作存储库(我认为),这仍然可以工作。当您需要执行跨越两个或更多服务的操作时,会出现此问题。例如,创建订单可能还需要调用发票服务来创建发票。但是如果出于某种原因,如果第二部分失败了,你也会想要回滚订单并向客户端返回一个有用的错误。
我不确定如何实现这一点,或者如果这是一个坏主意。我如何设置一个工作单元模式,允许多个服务和存储库(分离囚犯和SRP)?
答案 0 :(得分:5)
您的问题中有许多概念与技术部分无关。我一直试图在技术上解决它,但从长远来看总是失败。重要的还有商业专家所说的。如果正确应用,这就是 Domain Driven Design 闪耀的地方。我们作为开发人员试图假设业务如何运作,而不是真正问他们如何解决他们的问题。这导致我们一切都是交易的东西, 2PC , cripled and monolithical runtime monsters 。我的第一个问题是:"为什么订单必须与发票服务进行交易?" 。问一位商业专家。 "您是否因为发票系统中的错误而丢失了50M的订单?" 这对我来说似乎非常错误。向商务人士询问他们如何处理这种失败案例。
根据我的理解,即使没有发票,人们总是会接受订单。但是我缺乏你工作的业务背景,所以我不能给你一个非常彻底的答案。也许有一些我不知道的角落情况。
对您的问题的回答非常复杂,仅提供技术解决方案是错误的,但我会尝试指出一些可能有助于您进一步发展的资源。如果您正在设计复杂系统,那么查看域驱动设计将是一个良好的开端,因为许多此类问题都可以解决。
这可能无法解决您的问题,这可能会让您失望。但我更愿意给你一些提示,以便你可以更进一步,因为我一直在那里,并且做一切事务处理通常是在真实系统中处理事物的坏方法。
<强>参考文献:强>