NRules を使用すると、特定のドメインまたはオブジェクト モデルに関してルールを記述できます。そのため、データを保持するオブジェクトが必要です。これにより、それらのオブジェクトをルール セッションに挿入し、それらのオブジェクトをルールと照合することもできます。検証シナリオでは、次のいずれかを使用すると思います。
- サービス層からの DTO
- プレゼンテーション層からの ViewModel オブジェクト
- Build メソッドを呼び出す前の Builder オブジェクト (つまり、CustomerBuilder)
- ドメイン オブジェクト自体 (それを構築し、有効でない場合は検証して破棄します)
高いレベルでは、NRules のスイート スポットは、不安定なビジネス ロジックを安定したドメイン モデルの観点から表現することです。この場合、検証ロジックを 2 つのグループに分けることができます。1) 安定しており、ドメイン オブジェクトの固有の不変条件を定義する検証。つまり、顧客名は空白ではありません。2) 不安定な検証ロジック (つまり、特定の条件が満たされた場合に顧客が優先される)。次に、タイプ 1 の検証ロジックをドメイン モデル自体のアサーションとしてエンコードし、タイプ 2 の検証ロジックをそれらのドメイン オブジェクトに関するルールとしてエンコードします。
いずれにせよ、機械的なレベルでは、検証ルールが失敗した検証ごとに ValidationError を挿入し、最後にこれらの検証エラーのクエリセッションを挿入し、オブジェクトの構築を防止する必要があります。
ObjectUnderValidation match = null;
When()
.Match<ObjectUnderValidation>(() => match, x => x.ValidationCondition);
Then()
.Do(ctx => ctx.Insert(new ValidationError(match, "Message")));
後で検証を行うとき:
var session = factory.CreateSession();
session.Insert(myObjectUnderValidation);
session.Fire();
var errors = session.Query<ValidationError>().ToList();
if (errors.Any())
//Don't construct
else
//Construct
また、特定のシナリオで使いやすくするために、定型コードの一部をここで抽象化することもできます。