MVC2に流validationを備えたAutofac
-
29-09-2019 - |
質問
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
現在の登録コード:
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)'は登録されていません。
他のヒント
実装する複数のクラスから解決する IValidator
, 、 Autofacドキュメント いくつかのテクニックを示しています。これらの方法でアセンブリスキャンを使用できるとは思いません。バリデーターを個別に登録することができます。
名前で
builder.RegisterType<EmployeeViewModelValidator>().Named<IValidator>("employee");
var r = container.Resolve<IValidator>("employee");
キーによって
ドキュメントでは、列挙がキーとして使用されていることを示していますが、タイプをキーとして使用できます。 Resolve
を使用して validatorType
であなたに渡される CreateInstance
方法。
builder.RegisterType<EmployeeViewModelValidator>().Keyed<IValidator>(typeof(EmployeeViewModelValidator));
var r = container.Resolve<IValidator>(validatorType);
注:ドキュメントは、Autofacのバージョン2.3用です。 2.2.4を使用しているため、上記のメソッド名がドキュメントから異なる理由です。
お役に立てれば。
@adriftのもう1つの答えは、すばらしいアプローチです。いくつかのメモを追加するために、これは 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>
上記のように。これは、生涯の問題を防ぐのに役立ちます(あなたの例は、リクエストのライフタイムではなく、アプリケーションにバリデーターを関連付けます。)