IValidaableObject与单一责任


12

我喜欢MVC的可扩展性,它允许视图模型实现IValidatableObject,并添加自定义验证。

我尝试使我的控制器保持精简,使此代码成为唯一的验证逻辑:

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 2012年

+1注入一个单独的Validator类的好主意,解决了我必须访问数据库信息进行验证的问题!
magnattic 2015年

Answers:


7

就我个人而言,您的设计看起来很干净。

IValidatableObject意味着视图模型将提供一些简单属性无法提供的验证-注入真正的验证器,该验证器将调用服务/数据库/任何使您的设计保持清洁并确保您违反单一职责原则的视图模型-从本质上讲,它负责传输数据并验证传输的数据(无论是通过属性还是通过IValidatableObject或两者)。


4

拥有专用的验证对象可以确保您确实尊重SRP-无论如何,事实已经如此,因为验证模型的数据是视图模型的典型职责。

至于将实例注入视图模型,我看不出有什么问题。注入的内容几乎没有限制。


3

可以将ValidationContext(这是IValidatableObject.Validate()的arg)而不是将ILoginValidator注入VM构造函数中来获取Validator。

public IEnumerable<ValidationResult> Validate(ValidationContext vc)
{

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

}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.