我可以使用 Moq 集成在 UnitTests 中访问 Autofac 的全部功能吗

Can I access the full power of Autofac in UnitTests, using the Moq integration

我的项目(发生在 Orchard, though I don't think that's relevant) uses Autofac 之上。 我正在编写单元测试,我想在其中使用 Moq, and I'm using the Autofac/Moq integration 来消除所有依赖项以实现此目的。

这适用于作为构造函数参数传入的任何简单依赖项。 (Autofac 文档提供了如何实现此目的的详细信息 here)。

但是因为我从来没有 containerBuilder,所以我不知道如何充分利用 Autofac 的强大功能 - lamda registration, registering generics, marking properties to be auto-wired。等等

您提到的某些功能可以与 AutoMock class 一起使用,而有些功能将不再有意义。使用 AutoMock 我们不处理 ContainerBuilder class - 这是为了简单起见,我们不想编写所有这些注册指令,而是只注册我们感兴趣的指令。因此,从使用 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 并且不会再次构建它,所以这种延迟注册是没有意义的。如果我们想将另一个已经注册的对象传递给某个已注册的对象,那么我们可以简单地先解析它,然后再使用它。

总结如下:

  • autofac 功能通常可以通过 AutoMock 访问
  • 由于不在 ContainerBuilder 中注册而是在 IContainer 对象中注册的限制,某些功能不可用。其他东西可能还没有实现,可能会在未来交付。
  • 对于几乎所有情况,都有很好的解决方法,如上例所示