我有3个用Attribute注释的类
[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>();
在任何时候都没有将Type
类型注册到Autofac。
老实说,我建议不要在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>
。