簡體   English   中英

Unity IOC-如何基於自定義屬性注冊類型?

[英]Unity IOC - How to register Types based on Custom Attribute?

我有一個大型ASP.Net Web應用程序,該應用程序始終使用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)。

誰能闡明任何想法?

您只需要將返回的類型約束為使用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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM