2011-11-15 68 views
5

我試圖將autofac裝飾器支持功能應用於我的場景,但沒有成功。 它看起來像我的情況下,它沒有正確地將名稱分配給註冊。Autofac裝飾使用程序集掃描註冊的開放式仿製藥

有沒有辦法用名稱註冊掃描的程序集類型,以便以後可以在打開的通用裝飾器鍵中使用它?

或者我可能完全錯了,在這裏做一些不合適的事情?

builder.RegisterAssemblyTypes(typeof(IAggregateRepositoryAssembly).Assembly) 
    .AsClosedTypesOf(typeof(IAggregateViewRepository<>)) //here I need name, probably 
    .Named("view-implementor", typeof(IAggregateViewRepository<>)) 
    .SingleInstance(); 

builder.RegisterGenericDecorator(typeof(CachedAggregateViewRepository<>), 
    typeof(IAggregateViewRepository<>), fromKey: "view-implementor"); 

回答

13

下面是一個嘗試,而不是在Visual Studio的前面,因此重載決策可能不完全正確:

builder.RegisterAssemblyTypes(typeof(IAggregateRepositoryAssembly).Assembly) 
    .As(t => t.GetInterfaces() 
       .Where(i => i.IsClosedTypeOf(typeof(IAggregateViewRepository<>)) 
       .Select(i => new KeyedService("view-implementor", i)) 
       .Cast<Service>()) 
    .SingleInstance(); 
  • Named()Keyed()只是語法糖,它的成分與KeyedService關聯
  • As()接受一個Func<Type, IEnumerable<Service>>

您還需要:

using Autofac; 
using Autofac.Core; 
+0

就像一個魅力!非常感謝! – achekh

+0

太棒了!聽到那個消息很開心。 –

+1

這也適用於我。但我不相信演員()是需要的。 – luksan

2

如果你想清理你的註冊碼,你還可以定義以下附加擴展方法(非常詳細和基於對其他過載autofac源,但只有它需要進行一次定義):

using Autofac; 
using Autofac.Builder; 
using Autofac.Core; 
using Autofac.Features.Scanning; 

public static class AutoFacExtensions 
{ 
    public static IRegistrationBuilder<TLimit, TScanningActivatorData, TRegistrationStyle> 
     AsClosedTypesOf<TLimit, TScanningActivatorData, TRegistrationStyle>(
      this IRegistrationBuilder<TLimit, TScanningActivatorData, TRegistrationStyle> registration, 
      Type openGenericServiceType, 
      object key) 
     where TScanningActivatorData : ScanningActivatorData 
    { 
     if (openGenericServiceType == null) throw new ArgumentNullException("openGenericServiceType"); 

     return registration.As(t => 
      new[] { t } 
      .Concat(t.GetInterfaces()) 
      .Where(i => i.IsClosedTypeOf(openGenericServiceType)) 
      .Select(i => new KeyedService(key, i))); 
    } 
} 

這將讓你簡單地做到這一點:

builder.RegisterAssemblyTypes(typeof(IAggregateRepositoryAssembly).Assembly) 
    .AsClosedTypesOf(typeof(IAggregateViewRepository<>), "view-implementor") 
    .SingleInstance();