1 回答

TA貢獻1847條經驗 獲得超7個贊
將您的注冊更改為以下內容:
public static void AddGatewayServers(this IServiceCollection services)
{
services.AddTransient<Server1>();
services.AddTransient<Server2>();
services.AddScoped<Func<ServerType, IGatewayServer>>(provider => (key) =>
{
switch (key)
{
case ServerType.Type1: return provider.GetRequiredService<Server1>();
case ServerType.Type2: return provider.GetRequiredService<Server2>();
default: throw new InvalidEnumArgumentException(
typeof(ServerType), (int)key, nameof(key));
}
});
}
最重要的變化來自于:
services.AddTransient<IGatewayServer, Server1>();
services.AddTransient<IGatewayServer, Server2>();
對此:
services.AddTransient<Server1>();
services.AddTransient<Server2>();
MS.DI 中的注冊來自從服務類型 ( IGatewayServer) 到實現(Server1或Server2分別)的簡單字典映射。當你請求時,它在它的字典中Server1找不到。typeof(Server1)因此,解決方案是按具體類型注冊這些類型。
最重要的是,我使用了以下GetRequiredService方法:
provider.GetRequiredService<Server1>()
而不是GetService:
provider.GetService<Server1>()
GetRequiredService當注冊不存在時將拋出異常,這允許您的代碼快速失敗。
我更改了代表的注冊Transient:
services.AddTransient<Func<ServerType, IGatewayServer>>
到Scoped:
services.AddScoped<Func<ServerType, IGatewayServer>>
這可以防止它被注入到任何Singleton消費者中,因為 MS.DI 只能防止Scoped服務被注入到Singleton消費者中,但不會阻止Transient實例被注入到Scoped消費者中Singleton(但請確保啟用驗證)。如果您將其注冊為Transient,委托將被注入到消費者中,但是當您調用所請求的服務取決于生活方式Singleton時,這最終會在運行時失敗,因為這會導致Captive Dependencies?;蛘咚踔量赡軐е聝却嫘孤?,當您解析實現的組件時(糟糕?。?。將代表注冊為GetRequiredServiceScopedTransientIDisposableSingleton,但是,也會導致與俘虜依賴項相同的問題。所以Scoped是唯一明智的選擇。
而不是返回null一個未知數ServerType:
default:
return null;
我拋出一個異常,讓應用程序快速失?。?/p>
default:
throw new InvalidEnumArgumentException(...);
- 1 回答
- 0 關注
- 102 瀏覽
添加回答
舉報