首页 文章

如何在ASP.NET Core集成测试中覆盖其他容器的DI注册

提问于
浏览
1

我在asp.net core startup.cs文件中注册了以下内容:

public void ConfigureContainer(ContainerBuilder builder)
    {
       builder.RegisterType<UserService>().As<IUserService>();
    }

这是配置Autofac容器 . 我有另一个集成测试项目,我有一个CustomWebApplicationFactory类,我正在尝试替换IUserService接口的实现 .

protected override void ConfigureWebHost(IWebHostBuilder builder)
    {
        builder.ConfigureTestServices(services =>
        {
            services.AddSingleton<IUserService, TestUsersService>();
        });
    }

当我调试测试项目并且IUserService的实现仍然是UserService时,它似乎不起作用 .

我尝试使用ASP.NET Core内置的IServiceCollection直接在Startup.ConfigureServices方法中注册UserService,它在调试时有效:

services.AddSingleton<IUserService, UserService>();

那么,当我使用Autofac作为IoC容器并且集成测试项目将按照我的预期正常工作时,如何解决问题呢?

1 回答

  • 0

    您可能遇到了操作顺序问题 . 一般来说,最后胜利 . 这适用于Autofac和基本的Microsoft DI容器 .

    假设you've read through the docs on Autofac ASP.NET Core integration你会看到当 ConfigureContainer 到位时,操作顺序大致为:

    • WebHost特定的ConfigureServices

    • 启动类ConfigureServices

    • 启动类ConfigureContainer

    在添加ConfigureTestServices时,看起来(虽然我没有介入)它在WebHost和Startup类ConfigureServices之后运行......但它仍然在ConfigureContainer之前运行 .

    这很容易测试 - 创建一个具有三种不同实现的服务接口 . 在每个级别注册不同的实现 . 解析控制器中的接口 . 你得到了哪一个?那是最后一个跑 . 现在从应用程序中删除该注册,然后重试 . 你得到的下一个是什么?那是第二个到最后一个 . 等等 .

    Autofac采用预先构建的 IServicesCollection 并循环遍历它,将其添加到原生Autofac容器中 . 如果你修改了这个集合,那就很重要了 . Autofac无法控制ASP.NET Core中启动机制的执行顺序;它只知道ASP.NET Core说,"Here's the final service collection to go ahead and import!"如果's not happening at the right stage, you'll必须做以下两件事之一:

    • 使用Microsoft注册语言而不是本机Autofac,将您需要覆盖的注册移出 ConfigureContainer 并进入 ConfigureServices 方法之一 .

    • 以其他方式执行覆盖,例如使用 ASPNETCORE_ENVIRONMENTASPNETCORE_ENVIRONMENT 设置并提供 ConfigureTestContainer 方法 . (环境特定注册方法的示例在the docs中 . )

相关问题