2010-02-24 79 views
8

我现在开始使用DDD,我已经发现了一个很好的ValueObject实现,但我似乎找不到任何实体的好实现,我想要一个通用的基类实体类型一个ID(规格所需)和实现正确的相等操作。在C#中实现DDD实体类

什么是最优雅的解决方案?

回答

18

实体的唯一特征是它具有长寿命和(半)永久的身份。你可以通过执行IEquatable<T>来封装和表达。下面是做这件事:

public abstract class Entity<TId> : IEquatable<Entity<TId>> 
{ 
    private readonly TId id; 

    protected Entity(TId id) 
    { 
     if (object.Equals(id, default(TId))) 
     { 
      throw new ArgumentException("The ID cannot be the default value.", "id"); 
     } 

     this.id = id; 
    } 

    public TId Id 
    { 
     get { return this.id; } 
    } 

    public override bool Equals(object obj) 
    { 
     var entity = obj as Entity<TId>; 
     if (entity != null) 
     { 
      return this.Equals(entity); 
     } 
     return base.Equals(obj); 
    } 

    public override int GetHashCode() 
    { 
     return this.Id.GetHashCode(); 
    } 

    #region IEquatable<Entity> Members 

    public bool Equals(Entity<TId> other) 
    { 
     if (other == null) 
     { 
      return false; 
     } 
     return this.Id.Equals(other.Id); 
    } 

    #endregion 
} 
+0

你是什么意思半永久? – vorou 2013-02-24 17:57:36

+0

+1。这是一个大型应用程序的正常方法?我今天提出的一个问题正在吸引批评实体基类方法:https://softwareengineering.stackexchange.com/questions/364870/should-i-handle-all-nine-comparisons?noredirect = 1#comment 794683_364870。但是,它对我们来说效果很好。其中一条评论甚至被描述为贫血。 – w0051977 2018-01-29 18:07:28

+0

@ w0051977今天我不会那样写。确实,实体的特点是,如果它具有相同的ID,它就是相同的实体,但是'Equals'的实现在实际的代码库中没有帮助。 – 2018-01-29 21:49:01

0

我不确定您是否在遵循特定的库/示例代码或指导原则。 一个好的DDD解决方案将使用工厂实例化,持久性与领域模型分离(大多数ORM倾向于将两者捆绑在一起),明确定义领域边界,通过接口强制领域和操作。

我强烈推荐Jimmy Nilson的书“应用DDD和模式”一书。它深入讨论了DDD和最佳实践。这些例子也在C#中,这将适合您的项目。