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

edu*_*911 21 domain-driven-design

在Infrastructure层中对所有域层(模块,模型,实体,域服务等)的所有接口进行分组是否有意义?如果没有,创建一个将所有这些组合成共享库的"共享"项目/组件是否有意义?毕竟,"Infrastructure Layer"的定义包括"Domain,Application和UI层的共享库".

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

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

思考?

Geo*_*Geo 28

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

  • 优秀的Geobarteam.那只是给了我一个"呃"的时刻.是的,在域中定义接口,存储库应该在单独的程序集中实现(MySqlProviver,MsSqlProvider,XmlProvider等).某些类型的IOC容器(我喜欢Castle Windsor)用于在App层连接它.完善. (2认同)
  • 我唯一的问题是我的书说基础设施从不引用任何东西.UI-> App,Domain和Infra.App-> Domain和Infra.而且,Domain-> Infra.我知道,我知道,无论如何都应该是指导方针. (2认同)

Geo*_*Geo 5

我是 DDD 的新手,所以如果您不同意,请不要犹豫发表评论,因为我是来学习的。

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

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

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

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

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);
     }

}
Run Code Online (Sandbox Code Playgroud)

  • 这是很难确定的信息。我*认为*我发现的是,存储库的*接口*进入域层,因为它们为域定义了一个“接缝”。存储库的“实现”进入基础设施层。想象一下,决定从当前的应用程序上下文中完全提取您的域并构建一个全新的域。您需要存储库的接口,但不一定是实现。 (11认同)