【发布时间】:2013-02-26 15:23:07
【问题描述】:
在 MVC 中,我可以创建一个可以接受依赖项的模型验证器。我通常为此使用 FluentValidation。例如,这使我可以检查帐户注册是否未使用电子邮件地址(注意:这是一个简化的示例!):
public class RegisterModelValidator : AbstractValidator<RegisterModel> {
private readonly MyContext _context;
public RegisterModelValidator(MyContext context) {
_context = context;
}
public override ValidationResult Validate(ValidationContext<RegisterModel> context) {
var result = base.Validate(context);
if (context.Accounts.Any(acc => acc.Email == context.InstanceToValidate.Email)){
result.Errors.Add(new ValidationFailure("Email", "Email has been used"));
}
return result;
}
}
Web API 与 FluentValidation 不存在此类集成。这里有 couple 和 attempts,但都没有解决依赖注入方面的问题,只能使用静态验证器。
之所以难,是因为 MVC 和 Web API 的 ModelValidatorProvider 和 ModelValidator 的实现方式不同。在 MVC 中,这些是按请求实例化的(因此注入上下文很容易)。在 Web API 中,它们是静态的,并且 ModelValidatorProvider 为每种类型维护一个 ModelValidators 缓存,以避免对每个请求进行不必要的反射查找。
我一直在尝试自己添加必要的集成,但一直是stuck trying to obtain the Dependency Scope。相反,我想我会退后一步,询问是否有任何其他解决方案 - 是否有人提出了执行模型验证的解决方案,其中可以注入依赖项。
我不想在控制器中执行验证(我使用ValidationActionFilter 将其分开),这意味着我无法从控制器的构造函数注入中获得任何帮助。
【问题讨论】:
-
这是一个很好的问题,因为听起来您在提问之前确实做了研究。我不太确定在问这个问题时您是否真的在为能够注入依赖项而苦苦挣扎,或者问题是否是由于正在发生的缓存导致每次注入的任何依赖项都不会得到解决进行验证。这是我的团队遇到的情况,我在 FluentValidation 中打开了一个问题:github.com/JeremySkinner/FluentValidation/issues/108。您的以下解决方案可能对我们来说是一个可行的解决方案。
-
如果你想使用它们,我已经把它们放在了 nuget 上
标签: c# dependency-injection asp.net-web-api fluentvalidation