洋葱架构:我们应该在域实体中允许数据注释吗?

时间:2015-02-10 15:20:58

标签: c# asp.net-mvc serialization domain-driven-design onion-architecture

我希望将Onion Architecture实现到我们的ASP.NET MVC应用程序中。我理解将视图模型与域实体分开的必要性,但我发现自己正在编写冗余代码。存在冗余代码,因为我的视图模型和域实体看起来完全相同,除了我的视图模型具有[Serializable]数据注释。我需要这些模型可序列化,因为我使用的是ASP.NET会话状态,其中State Server需要对象可以序列化。

我个人觉得域实体不应该是可序列化的,因为它会依赖于特定的技术。但是,如何避免冗余代码?

我应该补充一点,我的服务方法依赖于这些可序列化的数据模型。

3 个答案:

答案 0 :(得分:6)

我会避免使用任何持久性或非域相关的东西来注释我的域对象。这样,我的Domain项目就不会依赖于另一个层了,我也不会把它与那些与Domain无关的东西弄得乱七八糟。虽然我们需要弯曲规则,但我更喜欢以不依赖于持久性细节的方式弯曲它们。

关键是要保持各层的目标集中在它们的目的上,因为它很容易混合起来并创造(及时)大泥球。

在您的情况下,我感觉您并没有真正拥有丰富的域名或者它的模型不正确。您似乎只有数据结构,而您的需求是CRUDy。

如果您确定应用程序不会变得更加复杂,即只是数据结构操作,那么您可以使用一个模型将它们用于所有目的。基本上你可以偷工减料,并将“商业”模式用于一切。不需要抽象和其他东西。

但是如果您认为应用程序将会发展或者它们是或将成为业务规则和流程,即您需要对业务所感知的行为进行建模,那么最好将事物保持非常分离,即使在此阶段它们也是如此似乎是完全相同的。

为了简化操作,您可以为视图模型定义一个(使用复制粘贴)并使用automapper将业务对象映射到视图模型。其他方法可能是您的查询服务/存储库/对象可以直接返回该视图模型(将查询结果映射到视图模型)

答案 1 :(得分:0)

Viewmodels可以包含域实体/模型。我的域实体是部分类,并且所有(最终)都从序列化的基本实体继承。由于我在一些视图模型中使用了我的域模型,因此我也在域模型上使用数据注释。您的域模型库不应依赖/引用其他任何内容(域驱动)。

答案 2 :(得分:0)

我本身不会将[Serializable]称为数据注释,因为它是核心.Net平台(mscorlib.dll)的一部分。数据注释是指用于在ASP.Net或实体框架中执行数据验证和其他操作的specific attributes

实体应该是[Serializable]吗?可能不是,但我认为这个属性不像来自外部,面向Web或面向持久性的库的其他属性那样“掺杂”到您的域层。它不会将您绑定到特定的第三方框架。

整个“冗余代码”问题取决于IMO您正在构建的系统类型。在真正的DDD应用程序中,域实体和视图模型之间的重复可能不会那么明显,单独的表示模型的好处通常会超过成本。关于该主题的一篇好文章:Is Layering Worth The Mapping