Asp.NET Core 一個(gè)接口的多個(gè)實(shí)現(xiàn)如何通過 DI 注冊(cè)?
咨詢區(qū)
LP13
我有三個(gè) Service 類實(shí)現(xiàn)了同一個(gè)接口,參考代碼如下:
public?interface?IService?{?}
public?class?ServiceA?:?IService?{?}
public?class?ServiceB?:?IService?{?}?
public?class?ServiceC?:?IService?{?}
我知道像其他的 DI 容器,比如 Unity 是在注冊(cè)實(shí)現(xiàn)類的時(shí)候通過不同的key來區(qū)分,在 ASP.NET Core 中做 AddService 時(shí)并沒有看到 key 或 name 參數(shù)的重載方法。
????public?void?ConfigureServices(IServiceCollection?services)
????{????????????
?????????//?How?do?I?register?services?of?the?same?interface?????????????
????}
????public?MyController:Controller
????{
???????public?void?DoSomething(string?key)
???????{?
??????????//?How?do?I?resolve?the?service?by?key?
???????}
????}
請(qǐng)問我該如何實(shí)現(xiàn)呢?
回答區(qū)
Miguel A. Arilla
我也遇到了這種場(chǎng)景,不過我是用 Func 做了一個(gè)折中方案。
首先:定義一個(gè) 委托。
public?delegate?IService?ServiceResolver(string?key);
然后:在 Startup.cs 中做多個(gè)實(shí)現(xiàn)類注冊(cè)。
services.AddTransient();
services.AddTransient();
services.AddTransient();
services.AddTransient(serviceProvider?=>?key?=>
{
????switch?(key)
????{
????????case?"A":
????????????return?serviceProvider.GetService();
????????case?"B":
????????????return?serviceProvider.GetService();
????????case?"C":
????????????return?serviceProvider.GetService();
????????default:
????????????throw?new?KeyNotFoundException();?//?or?maybe?return?null,?up?to?you
????}
});
后期:如果想使用的話,通過 key 從 Func 中提取具體的實(shí)例,參考代碼如下:
public?class?Consumer
{
????private?readonly?IService?_aService;
????public?Consumer(ServiceResolver?serviceAccessor)
????{
????????_aService?=?serviceAccessor("A");
????}
????public?void?UseServiceA()
????{
????????_aService.DoTheThing();
????}
}
為了做演示目的,我這里只用了 string 作為解析,你可以根據(jù)自己的場(chǎng)景具體實(shí)現(xiàn)。
點(diǎn)評(píng)區(qū)
在 Asp.Net Core 中是不支持這種多注冊(cè)的,這就有點(diǎn)尷尬了,Miguel A. Arilla 大佬提供的方案不錯(cuò),學(xué)習(xí)了。
評(píng)論
圖片
表情
