ASP.NET MVC アプリケーションでデータベース制約 (UNIQUE など) の検証を行う最良の方法は何か、DDD を念頭に置いて構築するのに最適な方法は何だろうと思っています。基礎となる層はアプリケーション層 (アプリケーション サービス)、ドメイン層 (ドメイン モデル) です。およびインフラストラクチャ層 (永続化ロジック、ロギングなど)。
私は多くの DDD サンプルを調べてきましたが、それらの多くが言及していないのは、リポジトリで検証を行う方法です (このタイプの検証が適していると思います)。これを行っているサンプルを知っている場合は、それらを共有していただければ幸いです。
具体的には、2 つの質問があります。実際の検証をどのように実行しますか? データベースにクエリを実行して、顧客名が既に存在するかどうかを明示的に確認しますか?それとも、データベースに直接挿入してエラーがあればキャッチしますか? 私は最初のものを好みます。これを選択する場合、リポジトリで行うべきですか、それともアプリケーション サービスの仕事にするべきですか?
エラーが検出されたら、それを ASP.NET MVC にどのように渡して、ユーザーにエラーについて適切に通知できるようにしますか? ModelStateDictionary
エラーがフォーム上で簡単に強調表示されるように、を使用することをお勧めします。
Microsoft Spain による N-Lyered アプリでは、IValidatableObject
インターフェイスを使用し、次のような最も単純なプロパティ検証がエンティティ自体に配置されます。
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
var validationResults = new List<ValidationResult>();
if (String.IsNullOrWhiteSpace(this.FirstName))
validationResults.Add(new ValidationResult(Messages.validation_CustomerFirstNameCannotBeNull, new string[] { "FirstName" }));
return validationResults;
}
エンティティが永続化される前に、プロパティが有効であることを確認するために Validate メッセージが呼び出されます。
void SaveCustomer(Customer customer)
{
var validator = EntityValidatorFactory.CreateValidator();
if (validator.IsValid(customer)) //if customer is valid
{
_customerRepository.Add(customer);
_customerRepository.UnitOfWork.Commit();
}
else
throw new ApplicationValidationErrorsException(validator.GetInvalidMessages<Customer>(customer));
}
次に、ApplicationValidationErrorsException を MVC アプリケーションでキャッチし、検証エラー メッセージを解析してModelStateDictionary
.
すべての検証ロジックを SaveCustomer メソッドに追加できます。たとえば、特定の列 (UNIQUE 列) を使用して顧客が既に存在するかどうかを確認するデータベースをクエリします。おそらくこれで問題ありませんが、validator.IsValid
(または同様のものが)私のためにこれを行うか、インフラストラクチャレイヤーで検証がもう一度実行されることを望みます(ここに属している場合はわかりません)。
どう思いますか?どのようにしますか?階層化されたアプリケーションのさまざまな検証手法について、より多くの洞察を得ることに非常に興味があります。
考えられる解決策 #1
検証ロジックをプレゼンテーション レイヤーで実行できず (Iulian Margarintescu が示唆するように)、サービス レイヤーで実行する必要がある場合、どのように検証エラーをプレゼンテーション レイヤーに渡しますか?
Microsoft はここで提案しています(リスト 5 を参照)。そのアプローチについてどう思いますか?