DDD を使用してアプリを構築していますが、仕様クラスをインスタンス化する場所や使用する場所を理解するのに苦労しています。
私のアプリは予約期間を多用するため、集計に追加されようとしている予約期間が、現在集計内にある別の期間と重ならないようにする仕様を持っています。以下のように。
/// <summary>
/// A specification that determines if the window passed in collides with other windows.
/// </summary>
public class BookingTemplateWindowDoesNotCollideSpecification : ISpecification<BookingScheduleTemplateWindow>
{
/// <summary>
/// The other windows to check the passed in window against.
/// </summary>
private readonly IEnumerable<BookingScheduleTemplateWindow> otherWindows;
/// <summary>
/// Initializes a new instance of the <see cref="BookingTemplateWindowDoesNotCollideSpecification" /> class.
/// </summary>
/// <param name="otherWindows">The other windows.</param>
public BookingTemplateWindowDoesNotCollideSpecification(IEnumerable<BookingScheduleTemplateWindow> otherWindows)
{
this.otherWindows = otherWindows;
}
/// <summary>
/// Determines whether the window passed in collides with other windows held inside this class.
/// </summary>
/// <param name="obj">The obj.</param>
/// <returns>
/// <c>true</c> if [is satisfied by] [the specified obj]; otherwise, <c>false</c>.
/// </returns>
public bool IsSatisfiedBy(BookingScheduleTemplateWindow obj)
{
return !this.otherWindows.Any(w => obj.DayOfWeek == w.DayOfWeek && w.WindowPeriod.IsOverlap(obj.WindowPeriod));
}
}
そして、仕様を使用して新しいウィンドウを追加できるようにするメソッドが集計にありました。既に永続化されたウィンドウの集約は、仕様コンストラクターに渡されます。
public virtual void AddWindow(DayOfWeek dayOfWeek, int startTime, int endTime)
{
var nonCollidingWindowSpecification = new BookingTemplateWindowDoesNotCollideSpecification(this.Windows);
var bookingWindow = new BookingScheduleTemplateWindow(this){
DayOfWeek = dayOfWeek,
WindowPeriod = new Range<int>(startTime, endTime)
};
if (nonCollidingWindowSpecification.IsSatisfiedBy(bookingWindow))
{
this.Windows.Add(bookingWindow);
}
}
私が苦労しているのは、仕様のタイプが必要になる可能性があるため、(この場合だけでなく、一般的なルールとしてアプリ全体で) 直接インスタンス化するのではなく、この仕様をクラスに注入する必要があると考えていることです。エンティティの状態に応じて変更します。しかし、REST API のような別のアプリケーション インターフェイスがあるかのように、MVC レイヤーから仕様を注入するのは汚いと感じ、使用する仕様についてのロジックが複製されます。
どの仕様を使用するかについてのロジックが別のアプリケーション インターフェイスで重複しないようにしながら、使用されている仕様の柔軟性を維持するにはどうすればよいでしょうか。
これは、ファクトリをエンティティに挿入し、そこから仕様を返したい場合で、ドメイン ロジックが上位層に流出しないようにする場合ですか? または、これを行うためのより良い/よりクリーンな/より簡単な方法はありますか?