DDD:在哪里保留域接口,基础结构?

问题描述 投票:23回答:3

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

我正在考虑围绕DDD层设计代码库:UI,应用程序,域,基础结构。这将分别创建4个项目。我的意思是,您是从域层引用基础结构层的。但是,如果您在Domain Layer项目中定义接口(例如IPost),则在定义IPostRepository.Save(IPost post)方法时必须从基础结构项目中引用Domain Layer项目时,您将具有循环引用。 。因此,“在共享库中定义所有接口”的想法。

也许存储库不应该期望对象被保存(IPostRepository.Save(IPost post);而是应该期望对象的参数(尽管在Save()中可能是很长的一组参数)。)可能是一个理想的情况,它显示对象何时变得过于复杂,应该为其寻找附加的值对象。

想法?

domain-driven-design
3个回答
30
投票

关于存储库的放置位置,我个人总是将存储库放置在专用的基础结构层(例如MyApp.Data.Oracle)中,但在域层中声明存储库必须符合的接口。在我的项目中,应用程序层必须访问域和基础结构层,因为它负责配置域和基础结构层。应用程序层负责将适当的基础结构注入到域中。该域不知道与哪个基础设施通信,只知道如何调用它。当然,我使用诸如Structuremap之类的IOC容器将依赖项注入到域中。再次说明,我并不是说DDD建议采用这种方式来构建项目,而只是设计应用程序的方式。干杯。


4
投票

我是DDD的新手,所以如果您不同意,请立即发表评论,因为我是在这里学习。

个人而言,我不明白为什么要从您的域中引用基础结构层。我认为域不应依赖于基础架构。 Domain对象应该完全不知道它们在哪个数据库上运行或使用哪种类型的邮件服务器发送邮件。通过从基础架构中抽象域,可以更轻松地重用;因为该域不知道其在哪个基础架构上运行。

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

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

必须使用存储库的Get(ID)或Create()方法通过存储库实例化根聚合。构造对象的具体存储库会自行传递,以便聚合程序可以保留其状态和子对象的状态,但不了解存储库的具体实现。例如:]]

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

}

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

IPostRepository.Save(Post post)

域完全不需要了解存储库。

Infrastructure层未被Domain或其他任何人引用,并且包含其他I / O相关内容中存储库的具体实现。在这种情况下,具有各种帮助程序的公共库称为“应用程序核心”,任何人都可以引用。


3
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.