【问题标题】:Domain driven design - How to check uniqueness of one property in domain object域驱动设计 - 如何检查域对象中一个属性的唯一性
【发布时间】:2024-05-18 18:25:02
【问题描述】:

我正在使用领域驱动设计开发应用程序。我一直在使用的模式之一是存储库模式。为简单起见,假设我有以下类和接口。

Car - 表示汽车领域概念的领域类。

public class Car {
  public int Id {get;private set;}
  public string SomeUniqueCode {get;private set;}
}

ICarRepository - 用于添加、删除或保存对 Car 对象的更改的接口。

public interface ICarRepository{
  Car  AddCar(Car c);
  void DeleteCar(Car c);
}

我的问题是,如何检查数据库中所有 Car 对象中 SomeUniqueCode 属性的唯一性?该属性在对象生命周期中的任何时候都由用户更改(不是自动生成的)。当然,一种解决方案是将唯一键放入数据库中,但这不是 DDD 的原则。我见过用于验证单个对象的规范模式。该模式将如何应用于一组 Car 对象?

规范类(我们称之为 CheckUniqueCarSpecification)访问 ICarRepository 是否合法?

【问题讨论】:

标签: domain-driven-design repository-pattern unique-constraint specification-pattern


【解决方案1】:

存储库模仿内存中的集合。我之前使用的是Contains 方法,而不是Find 方法,我想您也可以使用。查询层也可以用于此。就像您拥有CarRepository 一样,您也可以拥有CarQuery。尝试检查域中的唯一性有点令人讨厌。为了方便起见,我会进行检查,但仍然依赖数据库来引发异常,因为您也应该处理这种情况。为此使用规范模式可能会付出更多的努力。

由于存储库是一个“集合”,因此我不会在其中添加 CommitRollback

【讨论】:

  • 我的错。 Commit 和 Rollback 实际上在另一个接口(工作单元)中。我会解决的。
【解决方案2】:

使用 DomainService ICarCodesLibrary。

public class Car {
  ctor(string someUniqueCode, ICarCodesLibrary codes)
  {
    // the check
    codes.IsValidCode(someUniqueCode)
  }
  public int Id {get;private set;}
  public string SomeUniqueCode {get;private set;}
}

在你创建 Car 对象并注入它的地方实现接口。还要摆脱属性并使用字段。 ID 可以作为道具。

【讨论】:

    最近更新 更多