使用 Autofac 解析所有用 Attribute 注释为 IEnumerable<Type> 的 类
Resolve all classes that annotated with Attribute as IEnumerable<Type> using Autofac
我有 3 个 类 用属性
注释
[MyAttribute("xyz")]
class Class1
{}
//... other classes annotated with MyAttribute
我注册了所有类型
IContainer container ;
var builder = new ContainerBuilder();
//register all types annotated by MyAttribute
Assembly assembly = Assembly.GetExecutingAssembly();
builder.RegisterAssemblyTypes(assembly)
.Where(t => t.GetCustomAttribute<MyAttribute>() != null);
//other registered classes /services
container = builder.Build();
尝试解决:
//what this line(s) can be for only class that annotated by attribute
IEnumerable<Type> types = container.Resolve<IEnumerable<Type>>();
这个answer没有帮助
如何解析得到IEnumerable<Type>
当你这样做时:
builder.RegisterAssemblyTypes(assembly)
.Where(t => t.GetCustomAttribute<MyAttribute>() != null);
在幕后基本上这样做:
var types = assembly.GetTypes().Where(t => t.GetCustomAttribute<MyAttribute>() != null)
foreach(var type in types)
{
builder.RegisterType(type).AsSelf();
}
假设您有三种类型的属性:MyClass1
、MyClass2
、MyClass3
。这意味着注册 基本上 与:
builder.RegisterType<MyClass1>();
builder.RegisterType<MyClass2>();
builder.RegisterType<MyClass3>();
您在任何时候都没有在 Autofac 中注册类型 Type
。
老实说,无论如何,我建议不要使用 Autofac 注册超级泛型基类型,如 string
或 Type
。我会创建一个获取信息的工厂。这样,如果我需要有两个不同的 Type
列表,那么我可以通过使用两个不同的工厂接口轻松地将它们分开。
但是假设您无论如何都想这样做,实际上您必须注册 Type
而不是 MyClass1
或其他任何内容。 Autofac 不会开箱即用。你将不得不自己做。
我没有通过编译器得到这个 运行,但它应该类似于...
var types = assembly.GetTypes().Where(t => t.GetCustomAttribute<MyAttribute>() != null)
foreach(var type in types)
{
builder.RegisterInstance(type).As<Type>();
}
想法是您希望 Type
注册以便您可以列出这些东西,而不是您试图实例化您找到的东西。您不想 RegisterType(type)
因为这基本上意味着您希望 Autofac 能够 创建 type
的实例 ,而不是 跟踪这些类型的列表,以便稍后获取它们。这种混淆是将其置于您自己创建的工厂后面的另一个重要原因。
真的很简单:
public class TypeFactory
{
public IEnumerable<Type> Types {get;}
public TypeFactory(IEnumerable<Type> types)
{
this.Types = types;
}
}
然后:
var types = assembly.GetTypes().Where(t => t.GetCustomAttribute<MyAttribute>() != null)
var factory = new TypeFactory(types);
builder.RegisterInstance(factory);
然后解析 TypeFactory
而不是尝试直接解析 IEnumerable<Type>
。
我有 3 个 类 用属性
注释
[MyAttribute("xyz")]
class Class1
{}
//... other classes annotated with MyAttribute
我注册了所有类型
IContainer container ;
var builder = new ContainerBuilder();
//register all types annotated by MyAttribute
Assembly assembly = Assembly.GetExecutingAssembly();
builder.RegisterAssemblyTypes(assembly)
.Where(t => t.GetCustomAttribute<MyAttribute>() != null);
//other registered classes /services
container = builder.Build();
尝试解决:
//what this line(s) can be for only class that annotated by attribute
IEnumerable<Type> types = container.Resolve<IEnumerable<Type>>();
这个answer没有帮助
如何解析得到IEnumerable<Type>
当你这样做时:
builder.RegisterAssemblyTypes(assembly)
.Where(t => t.GetCustomAttribute<MyAttribute>() != null);
在幕后基本上这样做:
var types = assembly.GetTypes().Where(t => t.GetCustomAttribute<MyAttribute>() != null)
foreach(var type in types)
{
builder.RegisterType(type).AsSelf();
}
假设您有三种类型的属性:MyClass1
、MyClass2
、MyClass3
。这意味着注册 基本上 与:
builder.RegisterType<MyClass1>();
builder.RegisterType<MyClass2>();
builder.RegisterType<MyClass3>();
您在任何时候都没有在 Autofac 中注册类型 Type
。
老实说,无论如何,我建议不要使用 Autofac 注册超级泛型基类型,如 string
或 Type
。我会创建一个获取信息的工厂。这样,如果我需要有两个不同的 Type
列表,那么我可以通过使用两个不同的工厂接口轻松地将它们分开。
但是假设您无论如何都想这样做,实际上您必须注册 Type
而不是 MyClass1
或其他任何内容。 Autofac 不会开箱即用。你将不得不自己做。
我没有通过编译器得到这个 运行,但它应该类似于...
var types = assembly.GetTypes().Where(t => t.GetCustomAttribute<MyAttribute>() != null)
foreach(var type in types)
{
builder.RegisterInstance(type).As<Type>();
}
想法是您希望 Type
注册以便您可以列出这些东西,而不是您试图实例化您找到的东西。您不想 RegisterType(type)
因为这基本上意味着您希望 Autofac 能够 创建 type
的实例 ,而不是 跟踪这些类型的列表,以便稍后获取它们。这种混淆是将其置于您自己创建的工厂后面的另一个重要原因。
真的很简单:
public class TypeFactory
{
public IEnumerable<Type> Types {get;}
public TypeFactory(IEnumerable<Type> types)
{
this.Types = types;
}
}
然后:
var types = assembly.GetTypes().Where(t => t.GetCustomAttribute<MyAttribute>() != null)
var factory = new TypeFactory(types);
builder.RegisterInstance(factory);
然后解析 TypeFactory
而不是尝试直接解析 IEnumerable<Type>
。