MVCの拡張性の点が気に入って、ビューモデルでIValidatableObjectを実装し、カスタム検証を追加できるようになりました。
私はコントローラーを無駄のない状態に保ち、このコードが唯一の検証ロジックになるようにします。
if (!ModelState.IsValid)
return View(loginViewModel);
たとえば、ログインビューモデルはIValidatableObjectを実装し、コンストラクターインジェクションを介してILoginValidatorオブジェクトを取得します。
public interface ILoginValidator
{
bool UserExists(string email);
bool IsLoginValid(string userName, string password);
}
ビューモデルにインスタンスを注入するNinjectは、実際には一般的な方法ではないようですが、アンチパターンでさえあるのではないでしょうか。
これは良いアプローチですか?もっと良いものはありますか?
個人的には、あなたのデザインはきれいに見えます。
IValidatableObjectは、ビューモデルが単純な属性では提供できないいくつかの検証を提供することを意味します-サービス/データベースを呼び出す実際のバリデーターを注入します/何もデザインをクリーンに保ち、あなたを確実にしますしないでください違反します単一の責任の原則-ビューモデルは、基本的に、データの転送と転送されたデータの検証(属性またはIValidatableObjectのいずれか、またはその両方を介して)を担当します。
検証専用のオブジェクトを使用すると、SRPを確実に尊重することが保証されます。データを検証するのはビューモデルの一般的な責任であるため、SRPは尊重されます。
インスタンスをビューモデルに挿入することに関しては、私はそれについて何も悪いことを見ることができません。何に何を注入できるかに実質的に制限はありません。
ILoginValidatorをVMコンストラクターに注入する代わりに、ValidationContext(IValidatableObject.Validate()への引数)を使用してValidatorを取得できます。
public IEnumerable<ValidationResult> Validate(ValidationContext vc)
{
var loginValidator = (ILoginValidator)vc.GetService(typeof(ILoginValidator));
return loginValidator.Validate();
}