我的项目(建立在Orchard之上,虽然我没有认为相关的)使用Autofac。 我正在编写单元测试,我希望使用Moq来删除所有依赖项,并且我使用Autofac/Moq integration来实现此目的。
这适用于作为构造函数参数传递的任何简单依赖项。 (Autofac文档提供了如何实现此here)的详细信息。
但是因为我没有容器,所以我不知道如何使用很多Autofac的强大功能 - lamda registration,registering generics,将属性标记为auto-wired。等
答案 0 :(得分:2)
您提到的一些功能可以与AutoMock类一起使用,有些功能将不再有意义。使用AutoMock我们不处理ContainerBuilder类 - 这是为了简单起见,我们不希望编写所有那些注册指令,而只是注册那些对我们感兴趣的指令。因此,通过使用GetLoose或GetStrict方法创建AutoMock对象,我们只处理已构建的IContainer对象,以便解决问题。幸运的是,IContainer仍允许我们扩展其注册集,但Autofac不支持使用方便的扩展方法,因为它们是为了使用ContainerBuilder对象而构建的。这是完全合理的,因为对于Autofac透视图,在IContainer对象上扩展定义是不常见的。 ContainerBuilder应该处理注册,IContainer应该处理解析。
在此,我将介绍如何使用AutoMock使用自动连线属性功能:
using (var mock = AutoMock.GetLoose())
{
mock.Container.ComponentRegistry.Register(
RegistrationBuilder
.ForType<MyClass>()
.PropertiesAutowired()
.CreateRegistration<MyClass, ConcreteReflectionActivatorData, SingleRegistrationStyle>()
);
}
正如您现在所看到的,我们必须处理通常被扩展方法隐藏的autofac内部代码的所有丑陋。 PropertiesAutowired功能可以很容易地与AutoMock一起使用,但lamda注册将不再有意义。 lambda注册给我们的是在ContainerBuilder中注册的对象可以依赖于在将ContainerBuilder构建到IContainer期间解析的其他注册对象,因此我们不需要关心注册指令的顺序。在这里,我们已经准备好了IContainer并且它不会再次构建,因此这种注册的失败是毫无意义的。如果我们想要将另一个已注册的对象传递给某个已注册的对象,那么我们可以先解决它然后再使用它。
总结如下: