DDD:在哪里保留域接口,基础设施?

时间:2009-03-28 18:03:44

标签: domain-driven-design

在Infrastructure层中对所有域层(模块,模型,实体,域服务等)的所有接口进行分组是否有意义?如果没有,创建一个将所有这些组合成共享库的“共享”项目/组件是否有意义?毕竟,“基础架构层”的定义包括“域,应用程序和UI层的共享库”。

我正在考虑围绕DDD层设计我的代码库:UI,应用程序,域,基础架构。这将恭敬地创建4个项目。我的观点是,您从域层引用了基础架构层。但是,如果您在Domain Layer项目中定义接口,比如说IPost,那么当您在定义IPostRepository.Save(IPost post)方法时必须从Infrastructure项目引用Domain Layer项目时,您将有一个循环参考。因此,“定义共享库中的所有接口”的想法。

也许存储库不应该期望一个对象要保存(IPostRepository.Save(IPost post);而是期望对象的params(可能是Save()中的一长串params)。给定,这可能是一个理想的情况,表明一个对象变得过于复杂,应该为它寻找额外的值对象。

思想?

3 个答案:

答案 0 :(得分:28)

埃里克 我离开了一对夫妇,所以原谅我这么晚回答。 关于存储库的位置,我个人总是将存储库放在专用的基础结构层(例如MyApp.Data.Oracle)中,但是在域层中声明存储库必须符合的接口。
在我的项目中,应用层必须访问域和基础架构层,因为它负责配置域和基础架构层 应用程序层负责将适当的基础结构注入域中。域名不知道它与哪个基础设施通信,它只知道如何调用它。当然,我使用像Structuremap这样的IOC容器将依赖项注入域中。 我再次声明这不是DDD建议构建项目的方式,而是我构建应用程序的方式。 欢呼声。

答案 1 :(得分:3)

我在DDD中很安静,所以如果你不同意,请不要犹豫,因为我在这里学习。

我个人不明白为什么你应该从你的域引用基础设施层。在我看来,域名不应该依赖于基础设施。 Domain对象应该完全不知道它们在哪个数据库上运行,或者使用哪种类型的邮件服务器来发送邮件。通过从基础结构中抽象域,可以更容易地重用;因为域名不知道它在哪个基础设施上运行。

我在代码中所做的是从我的基础架构层引用域层(但不是相反)。存储库知道域对象,因为它们的作用是保留域的状态。我的存储库包含我的根聚合的基本CRUD操作(get(id),getall(),save(object),delete(object),并从我的控制器中调用。

我在上一个项目中做了什么(我的方法不仅仅是DDD,但它工作得很好)是我用接口抽象了我的存储库。必须通过传递具体类型的存储库来实例化根聚合:

必须使用存储库的Get(ID)或Create()方法通过存储库实例化根聚合。构造对象的具体Repository传递给自己,以便聚合可以保留其状态和子对象的状态,但不知道存储库的具体实现。 e.g:

public class PostRepository:IPostRepository
{
     ...
    public Post Create()
    {
        Post post=new Post(this);
        dbContext.PostTable.Insert(post);
        return post;
     }
     public  Save(post)
     {
         Post exitingPost=GetPost(post.ID);
         existingPost = post;
         dbContext.SubmitChanges();
     }
}

public class Post
{

     private IPostRepository _repository
     internal  Post(IPostRepository repository)
     {
        _repository = repository;
     }
     ...
    Public Save()
    {
        _repository.Save(this);
     }

}

答案 2 :(得分:3)

我建议你考虑Onion architecture。它非常适合DDD。我们的想法是,您的存储库接口位于Domain外部的一个层中,并直接引用实体:

IPostRepository.Save(Post post)

Domain根本不需要了解存储库。

域或其他任何人都没有引用基础结构层,并且包含其他I / O相关内容中的存储库的具体实现。在这种情况下,具有各种帮助程序的公共库称为Application Core,任何人都可以引用它。

相关问题