具有DbC支持的业务实体/价值对象框架

时间:2009-03-01 00:41:21

标签: domain-driven-design design-by-contract

我认为我在构建业务模型时花费的时间最多的是业务实体的验证,并确保实体对象及其关系保持良好的完整性。我对一个好的实体/价值对象框架的梦想将帮助我创建可重用的实体/价值对象,并像在数据库中一样轻松地创建关系的约束和规则,但因为我觉得这确实是业务规则,它们属于模型,应该是完全独立于数据库。

应该很容易定义Person对象的Name属性应该是必需的,并且应该要求Email属性并匹配某个正则表达式,并且这些规则应该可以很容易地重用f.ex.验证我的网络应用程序中的输入。

我对Linq to sql有很多经验,尽管使用它肯定很好,因为它不支持值对象和其他对象。我的问题是实体框架或NHibernate会更适合还是有更适合我需求的其他技术?

2 个答案:

答案 0 :(得分:0)

有一个small book I read last year by Steve Sanderson himself向我介绍了DDD概念。虽然这本书以ASP.NET MVC为预览版,但他真正关注MVC中的“M”作为一个真实而纯粹的领域模型 - 使用近一半的建模方法书(我非常喜欢)。他接近的一件事是在Aggregate Roots(显然)的上下文中使用Value Objects。但是,他还展示了如何使用Linq来表示实体以及Value Objects。

关键是,他注意到Linq的限制,它必须在每个对象上都有一个标识,包括Value Objects。他承认它打破了纯领域模式的方法;但是,这是使它与Linq-to-SQL一起工作的唯一方法。

他的解决方法是给你的价值对象一个身份;但是,将该标识置于内部,以使其不会暴露在您的模型之外。这将允许您在存储库中使用Linq链接和共享对象;而不是将它暴露给客户层 - 所以,就好像它们只是Value Objects一样。

我相信实体框架也有同样的要求。

C#示例如下。

public class MyEntity
{
  [Column(IsPrimaryKey = true
    , IsDbGenerated = true
    , AutoSync = AutoSync.OnInsert)]
  public int EntityID { get; set; }

  [Column(CanBeNull = false)]
  public string EntityProperty
  {
    get
    {
      // insert business rules here, if need be
    }
    set;
  }
}

public class MyValueObjectForMyEntity
{
  // make your identity internal
  [Column(IsPrimaryKey = true
    , IsDbGenerated = true
    , AutoSync = AutoSync.OnInsert)]
  internal int ValueObjectID { get; set; }

  // everything else public
  [Column(CanBeNull = false)]
  public string MyProperty { get; set; }
}

答案 1 :(得分:0)

即使看起来你在世界的.Net方面,我也强烈推荐Eric Evans的书“Domain Driven Design”。 (实际上,UML比Java更多,并且这些想法应该移植。)

这是一本模式书,但他提出了许多设计策略,主张将所有对象规则逻辑(“不变量”)粘贴到一个集中式域中;然后,他继续讨论一些常见的模式,并使像你这样的问题看起来更容易处理。好吧,如果不易处理,从长远来看至少更易于管理。