0

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

私の最善の推測は、バリデーターを間違って登録しているということです。

4

3 に答える 3

1

を実装する複数のクラスから解決するためIValidatorに、autofacのドキュメントにはいくつかのテクニックが示されています。これらの方法でアセンブリスキャンを使用することはできないと思います。バリデーターを個別に登録する必要があります。

名前で

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

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

キー別

ドキュメントには、キーとして使用されている列挙型が示されていますが、タイプをキーとして使用できます。これにより、メソッドで渡されたものをResolve使用して呼び出すことができます。validatorTypeCreateInstance

builder.RegisterType<EmployeeViewModelValidator>().Keyed<IValidator>(typeof(EmployeeViewModelValidator));    

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

注:ドキュメントはAutofacのバージョン2.3用です。私は2.2.4を使用しています。そのため、上記のメソッド名はドキュメントとは異なります。

お役に立てれば。

于 2010-10-13T04:36:28.623 に答える
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];
    }
}

重要な注意IContainerProvider:コンポーネントで使用しないでください。ApplicationContainer代わりに、IComponentContextまたはIIndex<K,V>上記のように使用してください。これは、ライフタイムの問題を防ぐのに役立ちます(例では、リクエストのライフタイムではなく、バリデーターをアプリケーションに関連付けます)。

于 2010-10-13T21:57:20.283 に答える
0

現在の登録コード:

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

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

現在の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)'は登録されていません。

于 2010-10-14T00:55:13.783 に答える