1 回答

TA貢獻(xiàn)1847條經(jīng)驗(yàn) 獲得超7個(gè)贊
將您的注冊(cè)更改為以下內(nèi)容:
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>();
對(duì)此:
services.AddTransient<Server1>();
services.AddTransient<Server2>();
MS.DI 中的注冊(cè)來自從服務(wù)類型 ( IGatewayServer) 到實(shí)現(xiàn)(Server1或Server2分別)的簡單字典映射。當(dāng)你請(qǐng)求時(shí),它在它的字典中Server1找不到。typeof(Server1)因此,解決方案是按具體類型注冊(cè)這些類型。
最重要的是,我使用了以下GetRequiredService方法:
provider.GetRequiredService<Server1>()
而不是GetService:
provider.GetService<Server1>()
GetRequiredService當(dāng)注冊(cè)不存在時(shí)將拋出異常,這允許您的代碼快速失敗。
我更改了代表的注冊(cè)Transient:
services.AddTransient<Func<ServerType, IGatewayServer>>
到Scoped:
services.AddScoped<Func<ServerType, IGatewayServer>>
這可以防止它被注入到任何Singleton消費(fèi)者中,因?yàn)?MS.DI 只能防止Scoped服務(wù)被注入到Singleton消費(fèi)者中,但不會(huì)阻止Transient實(shí)例被注入到Scoped消費(fèi)者中Singleton(但請(qǐng)確保啟用驗(yàn)證)。如果您將其注冊(cè)為Transient,委托將被注入到消費(fèi)者中,但是當(dāng)您調(diào)用所請(qǐng)求的服務(wù)取決于生活方式Singleton時(shí),這最終會(huì)在運(yùn)行時(shí)失敗,因?yàn)檫@會(huì)導(dǎo)致Captive Dependencies?;蛘咚踔量赡軐?dǎo)致內(nèi)存泄漏,當(dāng)您解析實(shí)現(xiàn)的組件時(shí)(糟糕?。?。將代表注冊(cè)為GetRequiredServiceScopedTransientIDisposableSingleton,但是,也會(huì)導(dǎo)致與俘虜依賴項(xiàng)相同的問題。所以Scoped是唯一明智的選擇。
而不是返回null一個(gè)未知數(shù)ServerType:
default:
return null;
我拋出一個(gè)異常,讓應(yīng)用程序快速失?。?/p>
default:
throw new InvalidEnumArgumentException(...);
- 1 回答
- 0 關(guān)注
- 114 瀏覽
添加回答
舉報(bào)