2009-11-24 100 views
11

在花了几个月的时间研究DDD方法论之后,我现在开始将这些概念应用到我公司的实际产品中。事实上,我一直致力于为未来的发展创建合适的可维护体系结构。N层开发中的DDD概念

我们已经决定利用以下技术:EF4(真V2),统一

我获得一直是最有启发性的信息量,不过,我留下了最好的几个问题做法:

问题1:的DTO - 最佳实践

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

  1. 传统方法:创建包含公共getter/setter方法,验证,&相应的业务逻辑POCO类。还要创建DTO并使用映射技术来管理它们。 (Automapper)
  2. 传统 - DTO:创建POCO类如上所述,但是,使用您的POCO作为传输对象。我的理解是,业务对象不应该离开域。
  3. 混合:我偶然发现了一个有趣的blog post,其中作者创建了他的POCO对象和DTO。在他的域对象内部,他创建了DTO的一个实例。这样可以更容易维护,因为您不像#1那样复制属性。像这样:
 
public abstract class POCOBase<T> : ValidationBase, IPOCO where T : DTOBase, new() 
{ 

public T Data { get; set; } 

public POCOBase() 
{ 
    Data = new T(); 
} 

public POCOBase(T dto) 
{ 
    Data = dto; 
} 
    } 

    public class SomePOCO : POCOBase { } 

    public class SomeDTO : DTOBase 

    { 

public String Name { get; set; } 

public String Description { get; set; } 

public Boolean IsEnabled { get; set; } 
} 


// EXAMPLES 
// POCOBase<SomeDTO> somePOCO = new SomePOCO(); 
// somePOCO.Data.Name = "blablabla"; 
// somePOCO.Validate(); 
// return somePOCO.Data; 

问题2:哪些对象应该由UI /服务层被退回?

这是DTO的重点。一个非常简单,轻量级的对象,只包含裸露的属性。它也不包含任何验证结果。如果我将我的DTO序列化回客户端,则应该假定客户端需要任何验证结果,如InvalidRules集合。例如,假设我正在与亚马逊的API合作。我想添加一本书到我的个人商店。如果我尝试添加图书而未发送ISBN,该服务可能会返回某种包含验证结果错误的响应组。

我错过了什么吗?我的印象是(至少从DDD“纯粹主义者”),DTOs不应该包含商业逻辑。在我看来,DTO不能提供足够的信息作为传输对象。无论是那个还是我需要一个封装了DTO和验证结果的新类型的Response对象。

问题3:IoC有多少?

这似乎明显,我认为我应该遵循的金科玉律:

“找出变化的应用 的部分,并从这些 是保持不变分开。“

对我来说,这是有道理的申请的IoC方面。为了减少依赖,我的介绍,业务逻辑和数据访问层通过一个IoC容器中的所有通信。在我的应用层包含通用接口和抽象,似乎我喜欢这个事实,我可以创建模拟测试存储库 - 通过简单地改变Unity的配置,我可以利用TDD。

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

+2

未来,请将每个问题陈述为单独的StackOverflow问题... – 2009-11-25 08:57:31

回答

18

我会尽力一次解决您的问题

回答1个

DTO的正交DDD,因为他们在应用程序的架构不同的地方用于不同的目的。也就是说,DTO在领域模型中没有地位,因为他们没有行为,因此会导致Anemic Domain Models

持久性无知的POCO是要走的路。杰里米米勒有很好的article that explains this concept

答案2

层坐域模型的顶部往往需要返回所定制的有问题的目的,自己的对象。

对于用户界面,MVVM模式效果特别好。 This article为WPF引入了MVVM,但该模式也像ASP.NET MVC中的魅力一样工作。

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

这需要大量映射在服务接口和域模型之间来回切换,但这是您必须为柔性设计支付的价格。您可能会发现AutoMapper在这方面很有帮助。

答案3

更IOC(真:DI)更好,但有一点你的问题让我吃惊:一个DI容器只能线了对象图,然后让开了路。对象不应该依赖DI容器。

有关更多详细信息,请参阅this SO answer

+0

感谢您的评论Mark。 我的理解是,当域对象无任何业务逻辑时,会出现贫血域模型。他们仍然是一群获得者/制定者。 ADM的另一点是逻辑(如验证)发生在对象之外而不是包含在内。 如果你回头看问题#1的混合方法......对我来说,在一个持续的无知域对象中创建一个DTO实例,并不一定构成一个贫血域模型。你说得对,因为它打破了DDD的原则。我可能不得不深入探讨这一点。 – Daniel 2009-11-25 12:56:23

+0

答案2是完美的。我有一个倾向,我可能需要创建自定义返回对象。感谢您对MVVM的建议......肯定会看一看。 – Daniel 2009-11-25 13:00:38

+0

我目前在我的ASP.NET web.config中配置我的DI容器,然后使用Global.asax进行设置。 对于你的答案3,如果我正确理解你的话: 那么为了实现TDD方法,我应该简单地在方法本身“即时”注册DI配置? – Daniel 2009-11-25 13:23:11