将域服务实现为存储库的扩展方法

时间:2011-01-01 13:01:56

标签: c# design-patterns domain-driven-design

我对域名服务的理解是他们执行超出相关存储库边界的任务(CRUD相关任务)。

由于.Net允许扩展方法,为什么不将域服务实现为存储库的扩展方法,从而减少在需要时实例化存储库和服务的需要?

我很感激任何评论。

4 个答案:

答案 0 :(得分:3)

  

“我对域服务的理解是他们执行的工作超出了相关存储库的边界(CRUD相关任务)。”

你的理解与我的不同,即:

  

域服务用于封装超出单个聚合/实体/值对象边界的逻辑。

存储库与存储有关,而不是域逻辑,因此这两者是非常不同的东西。

说实话,我在这里看到的关于服务的问题越多,我就越觉得围绕服务实际上存在一般性的混淆。我认为这可能是由于以下之间的含糊不清:

  1. 应用程序服务 - (UI调用的内容和事务开始的位置)
  2. 基础设施服务 - (类似IEmailSenderService,ICreditCardPaymentGateway)
  3. 域名服务 - (提供纯域逻辑,就像聚合/实体一样)
  4. Jimmy Bogard撰写了good article关于他们独特角色的文章。

    所以回答你的问题:这是一个坏主意,因为你混淆了两个截然不同的概念,并且会违反SRP

答案 1 :(得分:0)

第一个问题是您的对象将充满基础结构方法。

第二,你必须为这些包含扩展方法的静态类添加另一个层,这将分散你的服务层和域模型的代码恕我直言。

第三,你必须通过例如对象进行分类。标记接口,用于过滤它们能够调用的方法。

另一个问题是执行的上下文,当你在一个对象上调用crud方法时,它会在客户端还是服务器端执行?

另外违反了持久性无知域模型,

最后是在ORM中,它不是一个将被保存的对象,而是会保存一个会话,回忆Unit of Work模式。

答案 2 :(得分:0)

域服务可能很好地使用多个存储库。例如客户和订单存储库同时存在。

所以我认为这是一个坏主意。

答案 3 :(得分:0)

DDD中指定的服务是无状态方法(或者,在OO世界中,是一类相关方法),因此最终,扩展方法确实符合要求。

在您的存储库中使用扩展方法的最终结果将是从存储库公开服务接口,同时在存储库外部定义实现(这很好地减少了存储库的传出耦合)。通过使用委托模型定义服务方法,可以以更“OO友好”的方式实现类似的结果(在.Net 3.5及更高版本中,您可以利用Func<>Action<>),其中委托实现在别处定义(可以通过delegate based factory访问。)

public class MyRepository
{
    //Repository Specific Methods
    public DomainObject FindById(...)
    ...

    //"Service" Methods as Delegates
    public Func<DomainObject, SomeResult> ProcessDomainObjectAndGetBackSomeResult
    {
        get
        {
            return ServiceMethodFactory.ProcessDomainObjectAndGetBackSomeResult;
        }
    }
}