2016-11-13 72 views
0

我正在嘗試使用Mediatr和Autofac構建中介管道,但我正努力從Autofac解析驗證程序集合。使用Autofac解決IEnumerable問題

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");