Dependency injection 使用SimpleInjector注册FluentValidation的正确方法是什么?

Dependency injection 使用SimpleInjector注册FluentValidation的正确方法是什么?,dependency-injection,fluentvalidation,fluentvalidation-2.0,open-generics,simple-injector,Dependency Injection,Fluentvalidation,Fluentvalidation 2.0,Open Generics,Simple Injector,我能够使用FluentValidatorFactory注册FluentValidatorsAbstractValidators。但是,这感觉不太对,因为并非所有的IoC容器注册都发生在引导/合成根目录期间。取而代之的是: 组合根: public class SimpleDependencyInjector : IServiceProvider { public readonly Container Container; public SimpleDependencyInject

我能够使用
FluentValidatorFactory
注册FluentValidators
AbstractValidators
。但是,这感觉不太对,因为并非所有的IoC容器注册都发生在引导/合成根目录期间。取而代之的是:

组合根

public class SimpleDependencyInjector : IServiceProvider
{
    public readonly Container Container;

    public SimpleDependencyInjector()
    {
        Container = Bootstrap();
    }

    internal Container Bootstrap()
    {
        var container = new Container();

        container.Register< // ...register all non-fluent-validator types, then

        container.Verify();
        return container;
    }

    public object GetService(Type serviceType)
    {
        return ((IServiceProvider)Container).GetService(serviceType);
    }
}
SimpleInjector的流畅验证程序工厂实现

public class SimpleValidatorFactory : FluentValidatorFactory
{
    public SimpleValidatorFactory(SimpleDependencyInjector injector) 
        : base(injector)
    {
        var validators = AssemblyScanner.FindValidatorsInAssembly(
            Assembly.GetCallingAssembly());
        validators.ForEach(validator => 
            injector.Container.Register(
                validator.InterfaceType, validator.ValidatorType));
        injector.Container.Verify();
    }
}
SimpleInjector对开放泛型有很好的支持,我的所有fluent validator类都有类似于以下的签名:

public class SomeClassValidator : AbstractValidator<SomeClass>
{
    public SomeClassValidator([depedencies injected here])
    {
        // ... set up validation rules
    }
}
公共类SomeClassValidator:AbstractValidator
{
公共SomeClassValidator([此处注入依赖项])
{
//…设置验证规则
}
}
那么,有没有更好的方法在引导/合成根目录中注册验证器,而不是使用fluent的验证器工厂


附言@DotNetJunkie——如果你有,那就太好了

我想这是我自己弄明白的

1.)在合成根目录中注册fluent的open generic
IValidator
接口:

public class SimpleDependencyInjector : IServiceProvider
{
    public readonly Container Container;

    public SimpleDependencyInjector()
    {
        Container = Bootstrap();
    }

    internal Container Bootstrap()
    {
        var container = new Container();

        // some container registrations

        var assemblies = AppDomain.CurrentDomain.GetAssemblies().ToList();
        container.RegisterManyForOpenGeneric(typeof(IValidator<>), assemblies);

        // some more registrations

        container.Verify();
        return container;
    }

    public object GetService(Type serviceType)
    {
        return ((IServiceProvider)Container).GetService(serviceType);
    }
}
4.)在global.asax中将FluentValidatorFactory注册为验证工厂提供程序:

var injector = new SimpleDependencyInjector();
FluentValidationModelValidatorProvider.Configure(
    provider =>
    {
        provider.ValidatorFactory = new FluentValidatorFactory(injector);
    }
);

为什么要将容器包装在
SimpleDependencyInjector
抽象中?这似乎是多余的。一个关于Fluent验证的wiki页面将过于特定于框架。有数百个框架可以有一个wiki页面;要停止吗?@Steven,
SimpleDependencyInjector
类用于IServiceProvider的特定于simpleinjector的实现。我不想要任何对SI容器的引用,就像我在切换到SI之前没有引用IUnityContainer的代码一样。@Steven,关于wiki,你是对的。事实上,你已经有了一个维基,基本上可以准确地解释我的要求。我只是在点击之前读了几遍:
public class FluentValidatorFactory : ValidatorFactoryBase
{
    private IServiceProvider Injector { get; set; }

    public FluentValidatorFactory(IServiceProvider injector)
    {
        Injector = injector;
    }

    public override IValidator CreateInstance(Type validatorType)
    {
        return Injector.GetService(validatorType) as IValidator;
    }
}
var injector = new SimpleDependencyInjector();
FluentValidationModelValidatorProvider.Configure(
    provider =>
    {
        provider.ValidatorFactory = new FluentValidatorFactory(injector);
    }
);