我知道一些DI框架支持这一点(例如Ninject),但我特别想知道是否可以使用Autofac。
我希望能够向Autofac容器索取一个具体的类,然后返回一个实例,其中注入了所有适当的构造函数依赖项,而没有注册该具体类。即如果我从不绑定明确地,然后自动将具体类绑定到自身,就好像我调用了builder.Register<MyClass>();
这个有用的好例子是ViewModels。在MVVM中,分层是这样的,只有View依赖于ViewModel,并且通过松散键入,并且您不会对View进行单元测试。因此,无需为测试模拟ViewModel - 因此没有理由为每个ViewModel创建一个接口。因此,在这种情况下,通常的“注册此接口以解析此类”的DI模式是不必要的复杂性。明确的自我绑定,如builder.Register<MyClass>();
,在处理像具体类一样简单的事情时,也感觉像是一个不必要的步骤。
我知道Autofac文档中的reflection-based registration example,但这也不符合我的口味。我不希望提前注册每个可能的课程的复杂性(和缓慢);我希望框架能够在需要时为我提供所需的内容。约定优于配置,以及所有这些。
有没有办法配置Autofac所以它可以说“哦,这是一个具体的类型,没有人注册它,所以我只是表现得像已经注册了默认设置”?
答案 0 :(得分:14)
builder.RegisterTypesMatching(type => type.IsClass)
如果您look at the source,您将看到RegisterTypesMatching(和RegisterTypesFromAssembly)没有做任何反思。在这种情况下,所有Autofac都在注册一个接受类型的规则。在上面的例子中,我接受任何类型的类型。
对于RegisterTypesFromAssembly,Autofac会注册一条规则,说明“如果您尝试解析的类型具有Assembly ==指定的程序集,那么我将为您提供一个实例”。
所以:
与直接注册具体类型相比,这将在解析时具有一个性能,因为Autofac必须弄清楚,例如构造函数要求。也就是说,如果您使用默认实例范围(单例),则只在第一次解析该类型时才执行命中。下次它将使用已经创建的单例实例。
Autofac 2中的 更新:有一种更好的方法可以让容器解决任何问题。这涉及the AnyConcreteTypeNotAlreadyRegistered
registration source。
答案 1 :(得分:2)
怎么样:
builder.RegisterTypesFromAssembly(Assembly.GetExecutingAssembly());
没有像Peter Lillevold points out那样进行反思。