3 回答
TA贡献1772条经验 获得超8个赞
您可能会遇到操作顺序问题。一般来说,最后的胜利。这适用于 Autofac 和基本的 Microsoft DI 容器。
假设您已阅读有关 Autofac ASP.NET Core 集成的文档,您将看到,ConfigureContainer
操作顺序大致如下:
WebHost 特定的 ConfigureServices
启动类 ConfigureServices
启动类 ConfigureContainer
在适当的位置添加 ConfigureTestServices 时,它看起来(虽然我还没有通过)它在 WebHost 和启动类 ConfigureServices 之后运行......但它仍然在 ConfigureContainer 之前运行。
这很容易测试 - 创建一个具有三种不同实现的服务接口。在每个级别注册不同的实现。解析控制器中的接口。你得到了哪一个?那是最后一个运行。现在从应用程序中删除该注册并重试。你得到的下一个是什么?这是倒数第二个。等等。
Autofac 采用预构建IServicesCollection
并循环遍历它,将其添加到本机 Autofac 容器中。一旦发生这种情况,您是否修改集合都没有关系。Autofac 无法控制 ASP.NET Core 中启动机制的执行顺序;它只知道 ASP.NET Core 说:“这是要继续导入的最终服务集合!” 如果这不是在正确的阶段发生,您将不得不做以下两件事之一:
使用 Microsoft 注册语言而不是本机 Autofac,将您需要覆盖的注册移出
ConfigureContainer
和移入其中一种ConfigureServices
方法。以其他方式执行覆盖,例如使用
ASPNETCORE_ENVIRONMENT
设置Test
和提供ConfigureTestContainer
方法。(特定于环境的注册方法示例在文档中。)
TA贡献1842条经验 获得超12个赞
当像这样使用 ContainerBuilder 时:
public void ConfigureContainer(ContainerBuilder builder)
{
builder.RegisterType<UserService>().As<IUserService>();
}
您必须使用 ConfigureTestContainer 而不是 ConfigureTestServices,如下所示:
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
builder.ConfigureTestContainer<ContainerBuilder>(containerBuilder =>
{
containerBuilder.RegisterType<TestUsersService>().As<IUserService>();
});
}
这是调用ConfigureContainer后执行,并会正确地覆盖IUserService有TestUsersService
TA贡献1805条经验 获得超10个赞
对于来自 google 的那些,我想添加到 Michael 的出色答案中,该答案ConfigureTestContainer
不适用于Microsoft从 .NET Core 3.0 开始通过网络主机推荐的通用主机。然而,Autofac 团队的 Alistair Evans 提出了一种解决方法。不幸的是,它依赖于IStartupConfigureContainerFilter
可能会在 .NET 5.0 中删除的弃用。
这意味着当前在 .NET 5.0 中,当使用通用主机时,无法在集成测试中模拟外部 DI 容器注入的依赖项。
幸运的是,来自 ASP.NET 团队的 David Fowler正在调查这个问题。
- 3 回答
- 0 关注
- 213 浏览
添加回答
举报