Unity IOC - 如何注册基于自定义属性的类型?
Unity IOC - How to register Types based on Custom Attribute?
我有一个大型 ASP.Net 网络应用程序,它始终使用 Unity IOC。有许多 classes 需要创建为单例。
这是我的 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容器中具体注册了各个单例类型,有一个lifetime manager,如下:
container.RegisterType<IMySingleton1, MySingleton1>(new ContainerControlledLifetimeManager());
container.RegisterType<IMySingleton2, MySingleton2>(new ContainerControlledLifetimeManager());
但是,我想放弃以这种方式将每种类型专门注册为单例,通过使用自定义 SingletonAttribute 标记加载的程序集中的哪些类型需要是单例,然后,如果可能的话, 集体注册。
我为此目的创建了一个自定义属性:
[AttributeUsage(AttributeTargets.Class)]
public class SingletonAttribute : Attribute {}
并相应地标记 class 定义:
[Singleton]
public class MySingleton : IMySingleton
{
...
}
我已经设法 select 所有具有此自定义属性的类型:
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
我有一个大型 ASP.Net 网络应用程序,它始终使用 Unity IOC。有许多 classes 需要创建为单例。
这是我的 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容器中具体注册了各个单例类型,有一个lifetime manager,如下:
container.RegisterType<IMySingleton1, MySingleton1>(new ContainerControlledLifetimeManager());
container.RegisterType<IMySingleton2, MySingleton2>(new ContainerControlledLifetimeManager());
但是,我想放弃以这种方式将每种类型专门注册为单例,通过使用自定义 SingletonAttribute 标记加载的程序集中的哪些类型需要是单例,然后,如果可能的话, 集体注册。
我为此目的创建了一个自定义属性:
[AttributeUsage(AttributeTargets.Class)]
public class SingletonAttribute : Attribute {}
并相应地标记 class 定义:
[Singleton]
public class MySingleton : IMySingleton
{
...
}
我已经设法 select 所有具有此自定义属性的类型:
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