7

AbstractValidatorsを使用してFluentValidation を登録できFluentValidatorFactoryます。ただし、すべての IoC コンテナー登録がブートストラップ/コンポジション ルート中に行われるわけではないため、適切ではありません。代わりに、流暢なバリデーターは別の factory によって登録されます。

コンポジションルート:

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

それで、流暢なバリデーターファクトリーを使用する代わりに、バリデーターをブートストラップ/コンポジションルートに登録するより良い方法はありますか?

PS @DotNetJunkie - simpleinjector.codeplex.comにこれに関する wiki ページがあれば素晴らしいでしょう。

4

1 に答える 1

10

私はこれを自分で理解したと思います。

IValidator<T>1.)コンポジション ルートに流暢なオープン ジェネリック インターフェイスを登録します。

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.) FluentValidatorFactory を検証ファクトリ プロバイダーとして global.asax に登録します。

var injector = new SimpleDependencyInjector();
FluentValidationModelValidatorProvider.Configure(
    provider =>
    {
        provider.ValidatorFactory = new FluentValidatorFactory(injector);
    }
);
于 2012-04-02T22:54:31.337 に答える