.Net8 AddKeyedScoped鍵值key註冊服務異常

跳跃的键盘手發表於2024-06-20

異常描述:This service descriptor is keyed. Your service provider may not support keyed services.

場景:.Net8 WebAPI應用程式中使用AutoFac替代了預設的DI容器

當使用鍵值註冊服務後:

builder.Services.AddKeyedSingleton<ICache, BigCache>("big");

builder.Services.AddKeyedSingleton<ICache, SmallCache>("small");

程式啟動執行到:

var app = builder.Build(); 出現上述異常。

異常排查過程:

1.根據提示,由於鍵值服務註冊前,使用了Autofac的程式集註冊方式RegisterAssemblyTypes,一開始以為是服務已被註冊導致的。在程式集外部重寫了樣例服務,新增註冊後問題重現。

2.進一步懷疑是預設的容器鍵值註冊方式版本問題,於是切換使用了AutoFac容器的鍵值註冊方式:

ContainerBuilder.RegisterType<TImplements>().Keyed<TInterface>(key);

程式啟動後,不報錯了。以為問題解決了,結果在使用key獲取服務時IServiceProvider.GetKeyedService<T>(key),獲取不到。感覺應該還是沒有註冊成功。

3.上面已經開始懷疑DI容器版本問題,於是進一步排查。看了下預設容器DI版本Microsoft.Extensions.DependencyInjection是8.0沒啥問題。然後看了下Autofac-DI版本是8.0並且依賴的預設DI也是8.0。

也沒看出啥問題,但是nuget包管理器中Autofac-DI已經支援9.0,僥倖心理升級了一下。重新啟動程式,重試一下竟然可以了。。。

回過頭來想了一下,其實在第二步中使用Autofac鍵值註冊時,未出現異常,只是未註冊成功,這裡應該就說明Autofac-DI有問題了。

這裡也給了自己一個警醒,由於專案中引用的很多第三方元件,出現問題時往往對元件內部不太熟悉,無從下手解決,這個時候不妨先看下引用版本,有可能出現的問題已經被打補丁解決了,這樣至少可以少走很多彎路。

相關文章