我应该为实体和值对象创建名称空间吗?

时间:2017-12-12 09:42:06

标签: c# domain-driven-design

我正在使用DDD原则构建应用程序。我现在正在考虑应用程序核心中的命名空间结构。请看下面的想法:

Company.Application.Core.Entities
Company.Application.Core.ValueObjects

但是,我在GitHb上找不到一个应用程序的例子,它遵循这个约定。是否有特定原因不遵循此命名约定?

我还有实体的基类,即Company.Application.Core.Entities.Entity和值对象的基类,即Company.Application.Core.ValueObjects.ValueObject

备选方案是将所有值对象和实体放入:Company.Application.Core

2 个答案:

答案 0 :(得分:1)

您的方法可行,但此类构图讲述了您的代码专注于DDD构建块的故事,而不是关于域的内在功能。在DDD中,我们希望展示有关域的重要信息,技术问题不再是最重要的问题。

我建议创建以下命名空间:

YourCompany.YourApplicationName.YourParticularBoundedContextName.Application

在这里,您可以保留所有应用程序范围构建块,即Application Services和DTO,它们用于将参数传输到Application Services并从中返回数据。

YourCompany.YourApplicationName.YourParticularBoundedContextName.Domain

这是您将为Domain Scope构建块创建子名称空间的命名空间。

YourCompany.YourApplicationName.YourParticularBoundedContextName.Domain.AggregateName

每个Aggregate都有自己的命名空间,其中有Aggregate Root类,在此Aggregate,Repository接口内部使用的Entities和VOs,如果需要则使用Aggregate Factory等。 我不知道在C#中是否可行,但在Java中,为Aggregate提供单独的包(命名空间)还有另一个优点 - 您可以将Aggregate Root类设为public,将所有其他实体和VO内部用作包范围,所以它们在包(名称空间)之外是不可见的。这样你就可以为你的Aggregate构建一个没有人可以破解的公共API,因为有一个监护人:编译器:)

YourCompany.YourApplicationName.YourParticularBoundedContextName.Infrastructure

这里是存储库实现的位置(每个都在相应聚合的子名称空间中)

基类可以保存在:

YourCompany.YourApplicationName.Domain

甚至保存在单独的项目中,因为您可以尝试在其他应用程序中重复使用它。

有什么好处?使用代码时,您关注的是功能和领域,而不是技术方面。您将不得不更频繁地处理诸如“此流程流程如何”之类的问题,而不是“我希望立即查看所有实体和VO”,因此请让您的代码结构支持此问题。将实体(实际聚合部分)和VO(也是聚合部分)分隔成单独的命名空间,您丢失了与什么工作的信息。你可以简单地用大泥球结束,因为你会重用一些不应该重复使用的东西。

请看: https://github.com/BottegaIT/ddd-leaven-v2 它是Java中的一个示例项目,以这种方式完成打包。也许它会帮助你。

另一个例子是: https://github.com/VaughnVernon/IDDD_Samples 这是Vaughn Vernon关于DDD的书的样本。

还有一篇文章可能有用: http://www.codingthearchitecture.com/2015/03/08/package_by_component_and_architecturally_aligned_testing.html

答案 1 :(得分:0)

为您的实体类型(映射到数据库表等)和您的DTO类型(用于在应用程序的客户端和服务器层之间传递数据)使用单独的命名空间是非常标准的做法,即使.Entities.ValueObjects不是特别常见的选择。只要你一直使用它们,我认为不值得担心太多。