在MVC2中使用FluentValidation进行Autofac

时间:2010-10-13 01:52:38

标签: registration 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();
    }
}

我最好的猜测是我正在注册验证器错误。

3 个答案:

答案 0 :(得分:1)

要从实现IValidator的多个类中解析,autofac documentation会显示几种技术。我不认为你可以使用这些方法进行装配扫描;你将单独注册验证人。

按名称

builder.RegisterType<EmployeeViewModelValidator>().Named<IValidator>("employee");

var r = container.Resolve<IValidator>("employee");

按键

文档显示了一个用作键的枚举,但您可以使用该类型作为键,这样您就可以使用Resolve在{{1}中传递给您validatorType方法。

CreateInstance

注意:该文档适用于Autofac 2.3版。我正在使用2.2.4,这就是为什么上面的方法名称与文档不同。

希望这有帮助。

答案 1 :(得分:1)

@adrift的另一个答案是一个很好的干净方法。只是添加一些注释,这也适用于IIndex<K,V>关系类型,Autofac自动提供,例如:

public class ValidatorFactory : ValidatorFactoryBase {
    readonly IIndex<Type, IValidator> _validators;

    public ValidatorFactory(IIndex<Type, IValidator> validators) {
        _validators = validators;
    }

    public override IValidator CreateInstance(Type validatorType) {
        return _validators[validatorType];
    }
}

重要提示:请勿在组件中使用IContainerProviderApplicationContainer,而是使用IComponentContextIIndex<K,V>,如上所述。这将有助于防止生命周期问题(您的示例将验证程序与应用程序关联,而不是与请求生命周期关联。)

答案 2 :(得分:0)

当前注册码:

builder.RegisterType<EmployeeViewModelValidator>().Keyed<IValidator>(typeof(EmployeeViewModel));
builder.RegisterType<ValidatorFactory>().As<IValidatorFactory>();

_containerProvider = new ContainerProvider(builder.Build());

Current ValidatorFactory:

public class ValidatorFactory : ValidatorFactoryBase {
    readonly IIndex<Type, IValidator> _validators; 

    public ValidatorFactory(IIndex<Type, IValidator> validators) {
        _validators = validators;
    } 

    public override IValidator CreateInstance(Type validatorType) {
        return _validators[validatorType];
    }
}

CreateInstance中的相同错误:

请求的服务'FluentValidation.IValidator`1 [.EmployeeViewModel](FluentValidation.IValidator)'尚未注册。