将域服务实现为存储库的扩展方法
我对域服务的理解是他们执行超出相关存储库边界的任务(CRUD相关任务)。
由于.Net允许扩展方法,为什么不将域服务实现为存储库的扩展方法,从而减少在需要时实例化存储库和服务的需要?
我很感激任何评论。
“我对域服务的理解是,他们执行的工作超出了相关存储库的边界(CRUD相关任务)。”
您的理解与我的不同,即:
域服务用于封装超出单个聚合/实体/值对象边界的域逻辑。
存储库关注的是存储 ,而不是域逻辑,因此这两者是非常不同的东西。
说实话,我越是看到围绕域名服务的问题,我越觉得围绕什么域名服务实际上存在普遍的混淆。 我认为这可能是由于以下两者之间存在歧义:
- 应用程序服务 – (UI调用的内容和事务开始的位置)
- 基础设施服务 – (如IEmailSenderService,ICreditCardPaymentGateway)
- 域服务 – (提供纯域逻辑,就像聚合/实体一样)
吉米博加德写了一篇关于他们独特角色的好文章 。
所以回答你的问题:这是一个坏主意,因为你将混合两个截然不同的概念,并且会违反SRP
第一个问题是您的对象将充满基础结构方法。
第二,你必须为这些包含扩展方法的静态类添加另一个层,这将分散你的服务层和域模型恕我直言的代码。
第三,你必须通过标记界面对你的对象进行分类,以过滤他们能够调用的方法。
另一个问题是执行的上下文,当你在一个对象上调用crud方法时,它会被执行到客户端还是服务器端?
另外违反了持久性无知领域模型,
最后是在ORM中,它不是一个将被保存的对象,而是一个会话将被保存,召回工作单元模式。
域服务可能很好地使用多个存储库。 例如,客户和订单存储库同时存在。
所以我认为这是一个坏主意。
DDD中指定的服务是无状态方法(或者,在OO世界中,是一类相关方法),因此最终,扩展方法确实符合要求。
在存储库中使用扩展方法的最终结果是从存储库中公开服务接口,同时在存储库外部定义实现(这很好地减少了存储库的传出耦合)。 通过使用委托模型定义服务方法,可以以更“OO友好”的方式实现类似的结果(在.Net 3.5及更高版本中,您可以利用Func<>
和Action<>
),其中委托实现在别处定义(并且可以通过基于代表的工厂访问)。
public class MyRepository { //Repository Specific Methods public DomainObject FindById(...) ... //"Service" Methods as Delegates public Func ProcessDomainObjectAndGetBackSomeResult { get { return ServiceMethodFactory.ProcessDomainObjectAndGetBackSomeResult; } } }