[英]Resolve all classes that annotated with Attribute as IEnumerable<Type> using Autofac
I have 3 classes annotated with Attribute我有 3 个用 Attribute 注释的类
[MyAttribute("xyz")]
class Class1
{}
//... other classes annotated with MyAttribute
I registered all types我注册了所有类型
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();
Try to resolve:尝试解决:
//what this line(s) can be for only class that annotated by attribute
IEnumerable<Type> types = container.Resolve<IEnumerable<Type>>();
This answer didn't help这个答案没有帮助
How to resolve and get IEnumerable<Type>
如何解决和获取
IEnumerable<Type>
When you do this:当你这样做时:
builder.RegisterAssemblyTypes(assembly)
.Where(t => t.GetCustomAttribute<MyAttribute>() != null);
Under the covers it's basically doing this:在幕后,它基本上是这样做的:
var types = assembly.GetTypes().Where(t => t.GetCustomAttribute<MyAttribute>() != null)
foreach(var type in types)
{
builder.RegisterType(type).AsSelf();
}
Let's say you had three types with the attribute: MyClass1
, MyClass2
, MyClass3
.假设您有三种类型的属性:
MyClass1
、 MyClass2
、 MyClass3
。 That means the registration would basically be the same as:这意味着注册基本上与:
builder.RegisterType<MyClass1>();
builder.RegisterType<MyClass2>();
builder.RegisterType<MyClass3>();
At no point in there are you registering the type Type
with Autofac.在任何时候,您都不会向 Autofac 注册类型
Type
。
Honestly, I'd recommend against registering super generic base types like string
or Type
with Autofac anyway.老实说,我建议不要使用 Autofac 注册超级通用的基本类型,例如
string
或Type
。 I'd create a factory that gets the information.我会创建一个获取信息的工厂。 That way if I ever need to have two different lists of
Type
then I could separate them easily by using two different factory interfaces.这样,如果我需要有两个不同的
Type
列表,那么我可以通过使用两个不同的工厂接口轻松地将它们分开。
But let's say you want to do that anyway, you actually have to register Type
not MyClass1
or whatever.但是假设您无论如何都想这样做,您实际上必须注册
Type
而不是MyClass1
或其他什么。 Autofac doesn't do that sort of thing out of the box. Autofac 不会开箱即用。 You will have to do it yourself.
你必须自己做。
I don't have this running through a compiler, but it should be something like...我没有通过编译器运行它,但它应该是这样的......
var types = assembly.GetTypes().Where(t => t.GetCustomAttribute<MyAttribute>() != null)
foreach(var type in types)
{
builder.RegisterInstance(type).As<Type>();
}
The idea is that you want the Type
registered so you can list those things, not that you're trying to instantiate the things you located.这个想法是你想要注册
Type
以便你可以列出这些东西,而不是你试图实例化你找到的东西。 You don't want to RegisterType(type)
because that means, basically, that you want Autofac to be able to create an instance of type
, not track the list of those types so you can get them later .您不想
RegisterType(type)
因为这基本上意味着您希望 Autofac 能够创建type
的实例,而不是跟踪这些类型的列表,以便您以后可以获取它们。 This sort of confusion is another great reason to put this behind a factory of your own creation.这种混乱是将其置于您自己创建的工厂背后的另一个重要原因。
Really simply:真的很简单:
public class TypeFactory
{
public IEnumerable<Type> Types {get;}
public TypeFactory(IEnumerable<Type> types)
{
this.Types = types;
}
}
Then:然后:
var types = assembly.GetTypes().Where(t => t.GetCustomAttribute<MyAttribute>() != null)
var factory = new TypeFactory(types);
builder.RegisterInstance(factory);
Then resolve TypeFactory
instead of trying to resolve directly an IEnumerable<Type>
.然后解析
TypeFactory
而不是尝试直接解析IEnumerable<Type>
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.