1

我有一個大的ASP.Net Web應用程序,它在整個使用Unity IOC。有很多類需要創建爲單身人士。Unity IOC - 如何基於自定義屬性註冊類型?

這是我UnityConfig.cs代碼在我的啓動項目的第一部分:

// Create new Unity Container 
var container = new UnityContainer(); 

// Register All Types by Convention by default 
container.RegisterTypes(
    AllClasses.FromLoadedAssemblies(), 
    WithMappings.FromMatchingInterface, 
    WithName.Default, 
    WithLifetime.Transient); 

到現在爲止,我已經專門註冊的每個單類型在Unity IOC容器的,具有壽命管理器,如下所示:

container.RegisterType<IMySingleton1, MySingleton1>(new ContainerControlledLifetimeManager()); 
container.RegisterType<IMySingleton2, MySingleton2>(new ContainerControlledLifetimeManager()); 

然而,我想從這種方式專門登記每個類型作爲單移開,識別通過用標記它們其中加載的程序集內的類型需要是單身自定義SingletonAttribute和那麼,如果可能的話,集體註冊。

我創建爲目的的自定義屬性:

[AttributeUsage(AttributeTargets.Class)] 
public class SingletonAttribute : Attribute {} 

和標籤類定義相應:

[Singleton] 
public class MySingleton : IMySingleton 
{ 
... 
} 

我已經成功地選擇所有具有此自定義屬性的類型:

static IEnumerable<Type> GetTypesWithSingletonAttribute(Assembly assembly) 
{ 
    foreach (Type type in assembly.GetTypes()) 
    { 
     if (type.GetCustomAttributes(typeof(SingletonAttribute), true).Length > 0) 
     { 
      yield return type; 
     } 
    } 
} 

我在UnityConfig.cs下面的代碼:

// Identify Singleton Types 
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); 

List<Type> singletonTypes = new List<Type>(); 
foreach (var assembly in assemblies) 
{ 
    singletonTypes.AddRange(GetTypesWithSingletonAttribute(assembly)); 
} 

所以,我現在有所有需要的類型的枚舉,但我看不出如何將它們註冊爲按類型單身,同時還使他們能夠按照約定來解決(即所以Unity知道IMySingleton應該被解析爲MySingleton的一個實例)。

任何人都可以擺脫任何光線?

回答

2

你只需要約束類型返回到被註釋與Singleton屬性類型:

container.RegisterTypes(
    AllClasses.FromLoadedAssemblies() 
     .Where(t => t.GetCustomAttributes<SingletonAttribute>(true).Any()), 
    WithMappings.FromMatchingInterface, 
    WithName.Default, 
    WithLifetime.ContainerControlled); 

你可以註冊的一切,然後用ContainerControlledLifetimeManager覆蓋任何單身登記:

// Register All Types by Convention by default 
container.RegisterTypes(
    AllClasses.FromLoadedAssemblies(), 
    WithMappings.FromMatchingInterface, 
    WithName.Default, 
    WithLifetime.Transient); 

// Overwrite All Types marked as Singleton 
container.RegisterTypes(
    AllClasses.FromLoadedAssemblies() 
     .Where(t => t.GetCustomAttributes<SingletonAttribute>(true).Any()), 
    WithMappings.FromMatchingInterface, 
    WithName.Default, 
    WithLifetime.ContainerControlled, 
    null, 
    true); // Overwrite existing mappings without throwing 
+0

天才!正是我在找的東西。非常感謝。 :) – user2209634