2016-07-14 50 views
1

我有一個類,它使用AutoFac從二進制文件夾中的程序集構建一個容器。這基本上在dll的迭代,並註冊類與接口:如何在Autofac程序集掃描和註冊期間有選擇地更改使用期範圍?

private static void RegisterAssembly(ContainerBuilder builder, string assemblyNamePattern) 
    { 
     // Get the path to the currently executing assembly. We will load dll's from here only. 
     var path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); 
     if (String.IsNullOrWhiteSpace(path)) 
      return; 

     // Get a list of all the assemblies in this folder 
     var assembliesToRegister = (Directory.EnumerateFiles(path, assemblyNamePattern, SearchOption.TopDirectoryOnly) 
       .Select(Assembly.LoadFrom) 
       .ToArray()); 

     // Register the dll's 
     builder.RegisterAssemblyTypes(assembliesToRegister).AsImplementedInterfaces(); 
    } 

這是工作的罰款,我能創造我所需要的類的實例。我遇到的問題是這些類中有一些是單例(Redis緩存),因此需要註冊。在代碼中,他們定義使用懶惰<>:

private static readonly Lazy<CacheManager> _instance = new Lazy<CacheManager>(() => new CacheManager()); 
    public static ICacheManager Instance 
    { 
     get { return _instance.Value; } 
    } 

我想知道是,是否有某種方式來告訴AutoFac某些類需要註冊爲單身。我猜測我可以在構建完成後通過容器並將特定的定義更改爲單例,但如果我可以讓Autofac在註冊時自動執行它,那將更加可靠。

+0

您使用Autofac的哪個版本? –

+0

版本3.5.2(對不起,應該添加到該帖子)。我已經取得了一些進展,我正在註冊組件並使用來排除單例類。然後我分別將它們註冊爲SingleInstance().ExternalOwned()。不是一個好的解決方案,但學習速度很快 – SteveB

+0

使用LINQ來包含/排除某些類型實際上是您的問題的答案 - 您應該發佈並接受您自己的答案。 –

回答

1

作爲一種廉價的解決方案,當DLL的掃描,可以排除一個或多個接口:

 // Register the dll's, except the singleton ones. 
     builder.RegisterAssemblyTypes(assembliesToRegister) 
       .AsImplementedInterfaces() 
       .Except<IOne>() 
       .Except<ITwo>(); 

這使得一切,除了被自動註冊的單身人士。接下來,註冊的單身:

AddSingletonInstance<IOne>(builder, assembliesToRegister, "OneType"); 
AddSingletonInstance<ITwo>(builder, assembliesToRegister, "TwoType"); 

這依賴於掃描先前創建的組件列表中的泛型方法:

private static void AddSingletonInstance<T>(ContainerBuilder builder, Assembly[] assembliesToRegister, string typeName) 
    { 
     var singletonType = (from asm in assembliesToRegister 
         from tt in asm.DefinedTypes 
         where tt.Name == typeName 
         select tt).FirstOrDefault(); 

     if (singletonType != null) 
      builder.RegisterType(singletonType).As<T>().SingleInstance().ExternallyOwned(); 
    } 

它的效果並不理想,但它的作品。