[英]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.