سؤال

أحصل على "خطأ غير مسجل" أثناء التنفيذ في مكالمة 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> على النحو الوارد أعلاه. سيساعد هذا في منع مشكلات العمر (مثالك يربط صدقات بالتطبيق بدلاً من عمر الطلب.)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top