IValidatableObjectと単一の責任


12

ビューモデルでIValidatableObjectを実装し、カスタム検証を追加できるようにするMVCの拡張ポイントが気に入っています。

このコードを唯一の検証ロジックにして、コントローラーを無駄のないものにしようとしています。

if (!ModelState.IsValid)
    return View(loginViewModel);

たとえば、ログインビューモデルはIValidatableObjectを実装し、コンストラクターインジェクションを介してILoginValidatorオブジェクトを取得します。

public interface ILoginValidator
{
    bool UserExists(string email);
    bool IsLoginValid(string userName, string password);
}

ビューモデルにインスタンスを注入するNinjectは、実際には一般的な慣行ではないようです。

これは良いアプローチですか?より良いものはありますか?


別のオブジェクトで検証が必要な場合は、FluentValidationを試してください。fluentvalidation.codeplex.com/wikipage?title=mvcをご覧ください。
rmac

+1検証のためにデータベース情報にアクセスする必要があるという私の問題を解決する、別のValidatorクラスを挿入する素晴らしいアイデアです!
マグナティック

回答:


7

個人的には、あなたのデザインはきれいに見えます。

IValidatableObjectは、単純な属性では提供できない検証をビューモデルが提供することを意味します-サービス/データベース/デザインをクリーンに保ち、単一の責任原則に違反しないことを保証するものを呼び出す実際のバリデータを注入します-ビューモデルは基本的に、データを転送し、転送されたデータを検証します(属性またはIValidatableObject、あるいはその両方を介して)。


4

検証専用のオブジェクトを持つことで、SRPを実際に尊重することが保証されます-データを検証するのはビューモデルの典型的な責任であるため、とにかく既にそうでした。

インスタンスをビューモデルにインジェクトすることに関して、私はそれに関して何も悪いことを見ることができません。何に何を注入できるかに実質的に制限はありません。


3

ILoginValidatorをVMコンストラクターに挿入する代わりに、ValidationContext(IValidatableObject.Validate()の引数)を使用してValidatorを取得できます。

public IEnumerable<ValidationResult> Validate(ValidationContext vc)
{

var loginValidator = (ILoginValidator)vc.GetService(typeof(ILoginValidator));
return loginValidator.Validate();

}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.