MVC2 中的 Autofac 与 FluentValidation
我在 ValidatorFactory.CreateInstance 调用执行期间收到“未注册错误”。看来发送到该方法的类型是正确的。
我的注册代码:
...
builder.RegisterAssemblyTypes(assembly).Where(t => t.Name.EndsWith("Validator")).As<IValidator>();
builder.Register(d => _containerProvider).As<IContainerProvider>();
builder.Register(d => new ValidatorFactory(_containerProvider.ApplicationContainer.Resolve<IContainerProvider>())).As<IValidatorFactory>();
_containerProvider = new ContainerProvider(builder.Build());
我的 ValidatorFactory 代码:
public class ValidatorFactory : ValidatorFactoryBase {
private readonly IContainerProvider _containerProvider;
public ValidatorFactory(IContainerProvider containerProvider) {
_containerProvider = containerProvider;
}
public override IValidator CreateInstance(Type validatorType) {
return _containerProvider.ApplicationContainer.Resolve<IValidator>(validatorType);
}
}
我的视图模型和验证器代码:
[Validator(typeof(EmployeeViewModelValidator))]
public class EmployeeViewModel {
public EmployeeViewModel() {}
public EmployeeViewModel(string firstName) {
FirstName = firstName;
}
public string FirstName { get; private set; }
}
public class EmployeeViewModelValidator : AbstractValidator<EmployeeViewModel> {
public EmployeeViewModelValidator() {
RuleFor(x => x.FirstName)
.NotEmpty();
}
}
我最好的猜测是我注册的验证器是错误的。
I'm getting a 'not registered error' during execution in the ValidatorFactory.CreateInstance call. It appears the type being sent into the method is correct.
My registration code:
...
builder.RegisterAssemblyTypes(assembly).Where(t => t.Name.EndsWith("Validator")).As<IValidator>();
builder.Register(d => _containerProvider).As<IContainerProvider>();
builder.Register(d => new ValidatorFactory(_containerProvider.ApplicationContainer.Resolve<IContainerProvider>())).As<IValidatorFactory>();
_containerProvider = new ContainerProvider(builder.Build());
My ValidatorFactory code:
public class ValidatorFactory : ValidatorFactoryBase {
private readonly IContainerProvider _containerProvider;
public ValidatorFactory(IContainerProvider containerProvider) {
_containerProvider = containerProvider;
}
public override IValidator CreateInstance(Type validatorType) {
return _containerProvider.ApplicationContainer.Resolve<IValidator>(validatorType);
}
}
My view model and validator code:
[Validator(typeof(EmployeeViewModelValidator))]
public class EmployeeViewModel {
public EmployeeViewModel() {}
public EmployeeViewModel(string firstName) {
FirstName = firstName;
}
public string FirstName { get; private set; }
}
public class EmployeeViewModelValidator : AbstractValidator<EmployeeViewModel> {
public EmployeeViewModelValidator() {
RuleFor(x => x.FirstName)
.NotEmpty();
}
}
My best guess is that I'm registering the validators wrong.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
要从实现
IValidator
的多个类中进行解析,autofac 文档 显示了几种技术。我认为您不能使用这些方法来进行程序集扫描;您需要单独注册验证器。按名称
按键
文档显示了用作键的枚举,但您可以使用类型作为键,这样您就可以调用
Resolve 使用在
CreateInstance
方法中传递给您的validatorType
。注意:该文档适用于 Autofac 2.3 版本。我使用的是 2.2.4,这就是上面的方法名称与文档不同的原因。
希望这有帮助。
To resolve from multiple classes that implement
IValidator
, the autofac documentation shows a couple of techniques. I don't think you can use assembly scanning with these methods; you'll have register the validators individually.By Name
By Key
The documentation shows an enumeration being used as a key, but you could use the type as the key, which would let you call
Resolve
using thevalidatorType
being passed to you in theCreateInstance
method.Note: The documentation is for version 2.3 of Autofac. I'm using 2.2.4, which is why the method names above vary from the documentation.
Hope this helps.
@adrift 的另一个答案是一个很好的干净方法。只是添加一些注释,这也适用于 Autofac 自动提供的
IIndex
关系类型,例如:重要说明:不要使用
IContainerProvider 和
ApplicationContainer
— 而是使用上面的IComponentContext
或IIndex
。这将有助于防止生命周期问题(您的示例将验证器与应用程序而不是请求生命周期相关联。)The other answer by @adrift is a nice clean approach. Just to add some notes, this also works with the
IIndex<K,V>
relationship type, which Autofac provides automatically, e.g.:Important note: don't use
IContainerProvider
andApplicationContainer
in a component—instead useIComponentContext
orIIndex<K,V>
as above. This will help prevent lifetime issues (your example associates validators with the application rather than the request lifetime.)当前注册代码:
当前 ValidatorFactory:
CreateInstance 内出现相同错误:
请求的服务“FluentValidation.IValidator`1[.EmployeeViewModel] (FluentValidation.IValidator)”尚未注册。
Current Registration Code:
Current ValidatorFactory:
Same error inside CreateInstance:
The requested service 'FluentValidation.IValidator`1[.EmployeeViewModel] (FluentValidation.IValidator)' has not been registered.