簡體   English   中英

使用SimpleInjector注冊FluentValidation的正確方法是什么?

[英]What is the correct way to register FluentValidation with SimpleInjector?

我可以使用FluentValidatorFactory注冊FluentValidation AbstractValidators 但是,它感覺不對,因為並非所有IoC容器注冊都在bootstrap / composition root期間發生。 相反, 流利的驗證器由一個單獨的工廠注冊

組成根

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);
    }
}

一個抽象的流利驗證工廠,僅依賴於IServiceProvider

public abstract class FluentValidatorFactory : ValidatorFactoryBase
{
    private IServiceProvider Injector { get; set; }

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

    public override IValidator CreateInstance(Type validatorType)
    {
        return Injector.GetService(validatorType) as IValidator;
    }
}

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對開放泛型有很好的支持,我所有的流暢驗證器類都有類似如下的簽名:

public class SomeClassValidator : AbstractValidator<SomeClass>
{
    public SomeClassValidator([depedencies injected here])
    {
        // ... set up validation rules
    }
}

那么,有沒有更好的方法在bootstrap / composition根目錄中注冊驗證器,而不是使用fluent的驗證器工廠?

PS @DotNetJunkie - 如果你在simpleinjector.codeplex.com上一個wiki頁面會很棒

我想我自己想出來了。

1.)在組合根中注冊fluent的開放式通用IValidator<T>接口:

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);
    }
}

2.)擺脫SimpleValidatorFactory類。

3.)使FluentValidatorFactory成為一個非抽象的具體類:

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;
    }
}

4.)在Global.asax中注冊FluentValidatorFactory作為驗證工廠提供者:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM