Autofac مع FluentValidation في MVC2
-
29-09-2019 - |
سؤال
أحصل على "خطأ غير مسجل" أثناء التنفيذ في مكالمة ValitatorFactory.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());
رمز ValitatorFactory الخاص بي:
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());
ValitatorFactory الحالي:
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 [.employeViewModel] (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);
ملاحظة: الوثائق مخصصة للإصدار 2.3 من Autofac. أنا أستخدم 2.2.4 ، وهذا هو السبب في تختلف أسماء الأسلوب أعلاه من الوثائق.
أتمنى أن يساعدك هذا.
الجواب الآخر من 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>
على النحو الوارد أعلاه. سيساعد هذا في منع مشكلات العمر (مثالك يربط صدقات بالتطبيق بدلاً من عمر الطلب.)