[英]How to override and interface and call "base" interface in ASP.NET Core built-in DI container?
[英]How to override DI registration from other container in ASP.NET Core integration test
我在 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 容器并且集成测试项目将按预期正常工作时,我该如何解决问题?
您可能会遇到操作顺序问题。 一般来说,最后获胜。 这适用于 Autofac 和基本的 Microsoft DI 容器。
假设您已阅读有关 Autofac ASP.NET Core 集成的文档,您将看到当ConfigureContainer
就位时,操作顺序大致如下:
在适当的位置添加 ConfigureTestServices 时,它看起来(虽然我没有逐步完成)它在 WebHost 和启动类 ConfigureServices 之后运行......但它仍然在 ConfigureContainer 之前运行。
这很容易测试 - 创建一个具有三种不同实现的服务接口。 在每个级别注册不同的实现。 解析控制器中的接口。 你得到了哪一个? 那是最后一个运行。 现在从应用程序中删除该注册并重试。 你得到的下一个是什么? 这是倒数第二个。 等等。
Autofac 采用预先构建的IServicesCollection
并循环遍历它,将其添加到本机 Autofac 容器中。 一旦发生这种情况,您是否修改集合都没有关系。 Autofac 无法控制 ASP.NET Core 中启动机制的执行顺序; 它只知道 ASP.NET Core 说:“这是要继续导入的最终服务集合!” 如果这不是在正确的阶段发生,您将不得不做以下两件事之一:
ConfigureContainer
移到ConfigureServices
方法之一。Test
的ASPNETCORE_ENVIRONMENT
设置并提供ConfigureTestContainer
方法。 (环境特定注册方法的示例在文档中。)像这样使用 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 之后执行的,并将使用TestUsersService
正确覆盖IUserService
对于来自 google 的那些,我想添加到 Michael 的出色回答中,即ConfigureTestContainer
不适用于Microsoft从 .NET Core 3.0 开始通过 Web 主机推荐的通用主机。 然而,Autofac 团队的 Alistair Evans 提出了一种解决方法。 不幸的是,它依赖于可能会在 .NET 5.0 中删除的已弃用的IStartupConfigureContainerFilter
。
这意味着当前在 .NET 5.0 中,当使用通用主机时,无法在集成测试中模拟外部 DI 容器注入的依赖项。
幸运的是,来自 ASP.NET 团队的 David Fowler 正在调查这个问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.