2016-11-13 3 views
0

Я пытаюсь построить конвейер медиатора с Mediatr и Autofac, но я пытаюсь решить набор валидаторов из Autofac.Разрешить IEnumerable с Autofac

public class MediatorPipeline<TRequest, TResponse> 
    : IAsyncRequestHandler<TRequest, TResponse> where TRequest : IAsyncRequest<TResponse> 
{ 
    private readonly IAsyncRequestHandler<TRequest, TResponse> _inner; 
    private readonly IEnumerable<IValidator<TRequest>> _validators; 

    public MediatorPipeline(IAsyncRequestHandler<TRequest, TResponse> inner, 
     IEnumerable<IValidator<TRequest>> validators) 
    { 
     _inner = inner; 
     _validators = validators; 
    } 
    ... 
} 

Когда я положил IValidator<TRequest> в конструкторе он решает в порядке, но когда я ставлю IEnumerable<IValidator<TRequest>> это не удается, за исключением:

Контейнер или локатор службы не настроен должным образом или обработчики не зарегистрированы с контейнером , ---> Autofac.Core.DependencyResolutionException: произошла ошибка при активации конкретной регистрации.

Вот мой регистрационный код:

builder.RegisterAssemblyTypes(assembly) 
    .Where(t => t.IsClosedTypeOf(typeof(IValidator<>))) 
    .AsImplementedInterfaces() 
    .InstancePerLifetimeScope(); 

У меня был один и тот же результат с этой альтернативной регистрации:

var openGenericType = typeof(IValidator<>); 

var query = from type in assembly.GetTypes().Where(c => !(c.GetTypeInfo().IsAbstract || c.GetTypeInfo().IsGenericTypeDefinition)) 
      let interfaces = type.GetInterfaces() 
      let genericInterfaces = interfaces.Where(i => i.GetTypeInfo().IsGenericType && i.GetGenericTypeDefinition() == openGenericType) 
      let matchingInterface = genericInterfaces.FirstOrDefault() 
      where matchingInterface != null 
      select new { matchingInterface, type }; 

foreach (var pair in query) 
{ 
    builder.RegisterType(pair.type).As(pair.matchingInterface); 
} 

Любые предложения высоко ценится!

+0

Вы проверили, чтобы увидеть, что ваша логика фильтрации на самом деле возвращает типы, которые вы ожидаете? В вашей второй альтернативе вы можете отлаживать и видеть, что цикл foreach фактически перебирает все типы, которые вы ожидаете? Просто убедитесь, что проблема связана с регистрацией Autofac, а не с типом запроса. –

ответ

0

Во-первых, было бы неплохо увидеть все исключение - внутреннее исключение включено - с трассировкой стека.

Autofac предоставляет удобный метод расширения, AsClosedTypesOf, который вы можете использовать этот путь:

builder 
    .RegisterAssemblyTypes(ThisAssembly) 
    .AsClosedTypesOf(typeof(IValidator<>)) 
    .InstancePerLifetimeScope(); 

Это сделает работу за вас, так что вам не придется идти в глубокое отражение зарегистрировать свои валидаторы.

тогда Вы должны зарегистрировать обработчик и декоратор на них сверху:

builder 
    .RegisterAssemblyTypes(ThisAssembly) 
    .AsClosedTypesOf(typeof(IAsyncRequestHandler<,>), "base-handler") 
    .InstancePerDependency(); 

builder.RegisterGenericDecorator(
    typeof(MediatorPipeline<,>), 
    typeof(IAsyncRequestHandler<,>), 
    "base-handler"); 
Смежные вопросы