11

在花了几个月的时间研究 DDD 方法之后,我现在开始将这些概念应用到我公司的实际产品中。事实上,我的任务是为未来的开发创建一个合适且可维护的架构。

我们决定使用以下技术:EF4(真正的 v2)、Unity

我获得的信息量最有启发性,但是,在最佳实践中我还有几个问题:

问题 #1: DTO - 最佳实践

我有我的域对象(PO​​CO 类)。有几种方法可以实现这些类。

  1. 传统方法:创建包含公共 getter/setter、验证和适当业务逻辑的 POCO 类。还可以创建 DTO 并使用映射技术来管理它们。(自动映射器)
  2. 传统 - DTO:创建如上所述的 POCO 类,但是,使用您的 POCO 作为传输对象。我的理解是业务对象永远不应该离开域。
  3. Hybrid:我偶然发现了一篇有趣的博客文章,其中作者创建了他的 POCO 对象和 DTO。在他的领域对象中,他创建了一个 DTO 实例。这使得可维护性更容易,因为您不会像 #1 那样复制您的属性。像这样:
公共抽象类 POCOBase<T> : ValidationBase, IPOCO 其中 T : DTOBase, new()
{

 公共 T 数据 { 获取;放; }

 公共 POCOBase()
 {
     数据 = 新 T();
 }

 公共 POCOBase(T dto)
 {
     数据 = dto;
 }
  }

  公共类 SomePOCO : POCOBase { }

  公共类 SomeDTO : DTOBase

  {

 公共字符串名称 { 获取;放; }

 公共字符串描述{get; 放; }

 公共布尔 IsEnabled { 获取;放; }
}


// 例子
// POCOBase<SomeDTO> somePOCO = new SomePOCO();
// somePOCO.Data.Name = "blablabla";
// somePOCO.Validate();
// 返回一些POCO.Data;

问题 #2: UI/服务层应该返回哪些对象?

这就是 DTO 的重点。一个非常简单的轻量级对象,仅包含裸属性。它也不包含任何验证结果。如果我将我的 DTO 序列化回客户端,则应假定客户端需要任何验证结果,例如 InvalidRules 集合。

例如,假设我正在使用亚马逊的 API。我想在我的个人商店中添加一本书。如果我尝试在不发送 ISBN 的情况下添加一本书,该服务可能会返回某种包含验证结果错误的响应组。

我错过了什么吗?我的印象(至少来自 DDD “纯粹主义者”)认为 DTO 不应该包含业务逻辑。在我看来,DTO 没有提供足够的信息作为传输对象。要么,要么我需要一种封装 DTO 和验证结果的新型 Response 对象。

问题 3: 多少 IoC 太多了?

在我看来,我应该遵循黄金法则:

“识别应用程序中不同的部分,并与那些保持不变的部分分开。”

对我来说,这在应用 IoC 方面是有道理的。为了减少依赖,我的表示层、业务逻辑层和数据访问层都通过 IoC 容器进行通信。我的应用层包含通用接口和抽象。比这更多地使用 IoC 似乎有点矫枉过正。我喜欢我可以创建模拟测试存储库这一事实 - 只需更改 Unity 的配置,我就可以使用 TDD。

我希望我已经清楚地说明了这些问题。提前感谢您的帮助!

4

1 回答 1

20

我将尝试一次解决您的问题。

答案 1

DTO 与 DDD 正交,因为它们在应用程序架构的不同位置服务于不同的目的。也就是说,DTO 在域模型中没有位置,因为它们没有行为,因此会导致贫血域模型

具有持久性无知的 POCO 是要走的路。Jeremy Miller 有一篇很好的文章解释了这个概念

答案 2

位于域模型之上的层通常需要返回为相关目的量身定制的自己的对象。

对于 UI,MVVM 模式效果特别好。本文介绍了用于 WPF 的 MVVM,但该模式在 ASP.NET MVC 中也很有魅力。

对于 Web 服务,这就是 DTO 模式适用的地方。WCF 数据合同是 DTO,以防您想知道 :)

这将需要在服务接口和领域模型之间来回进行大量映射,但这就是您必须为 Supple Design 付出的代价。您可能会发现AutoMapper在这方面很有帮助。

答案 3

IoC(真的:DI)越多越好,但是关于您的问题的一件事让我印象深刻:DI 容器应该只连接对象图,然后让开。对象不应依赖 DI 容器。

有关更多详细信息,请参阅此 SO 答案

于 2009-11-25T09:13:20.403 回答