在.NET Core中处理一个接口多个不同实现的依赖注入问题
前言
近段時間在準備公司的技術分享,所以這段時間將大部分時間放在準備分享內容上去了。博客也就停了一下下。
在.NET Core中處理依賴注入問題時,往往是定義好了一個操作規范的接口,會有N多個基于不同技術的實現,根據實際情況在項目中去使用某一個實現。
但是偶爾會出現這樣的情況,在某一個地方,需要同時使用到兩種或兩種以上的實現,這個時候我們要怎么處理呢?
借助Autofac等第三方組件時,是可以很容易的實現,但是在寫一些基礎類庫時會避免直接引用太多依賴組件。
所以這里是只用微軟自帶的DI(Microsoft.Extensions.DependencyInjection)去處理。
例子引入
現在有一個接口和兩個實現類。
public interface IDemoService{ ??string Get(); }
?public class DemoServiceA : IDemoService{ ?
??public string Get() ? ?{ ? ?
?? ? ?return "Service A";} }
?
?public class DemoServiceB : IDemoService{ ?
??public string Get() ? ?{ ? ? ?
?? ?return "Service B";} }
常規的方法,我們先在Startup中的ConfigureServices方法中添加我們的service。
public void ConfigureServices(IServiceCollection services){services.AddSingleton<IDemoService, DemoServiceA>();services.AddSingleton<IDemoService, DemoServiceB>();services.AddMvc(); }然后在控制器中使用
private IDemoService _serviceA;private IDemoService _serviceB;
public ValuesController(IDemoService serviceA, IDemoService serviceB){_serviceA = serviceA;_serviceB = serviceB; }
// GET api/values
[HttpGet]
public string Get(){ ?
?return $"{_serviceA.Get()}-{_serviceB.Get()}"; }
我們的預期結果是:Service A-Service B,可是上面代碼的實際結果卻并不像我們想的那么簡單!!
可以看到這里輸出的都是Service B,連Service A的影子都沒有看到。
其實,從代碼都可以看出來,它只能拿到其中一個Service的實現類!
那么我們要息怎樣處理才能達到我們想要的效果呢?
其實思路比較簡單,上面導致不能拿到對應實現類,本質上來講應該說是它區分不了那個才是想要的!我們想個辦法讓它能區分就好了。
處理方法
給我們的Service起個別名!
先是Startup中的ConfigureServices方法。
public void ConfigureServices(IServiceCollection services){services.AddSingleton<DemoServiceA>();services.AddSingleton<DemoServiceB>();services.AddSingleton(factory =>{Func<string, IDemoService> accesor = key =>{ ? ? ? ?? ? ? ? ? ??if (key.Equals("ServiceA")){ ? ? ? ? ? ? ?
? ? ? ? ? ? ? ?return factory.GetService<DemoServiceA>();} ? ? ? ? ?
? ? ? ? ? ? else if (key.Equals("ServiceB")) ? ? ? ?
? ? ? ? ? ??{ ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? ?return factory.GetService<DemoServiceB>();} ? ? ? ?
? ? ?? ?? ?else{ ? ? ? ? ? ?
? ? ?? ?? ?? ?throw new ArgumentException($"Not Support key : {key}");}}; ? ? ? ?return accesor;});services.AddMvc(); }
這里并沒有直接向上面那樣一次性指定接口和對應的實現類,而是用了AddSingleton的另一個重載方法。
先將實現類注冊一下
然后再注冊一下Func<string, IDemoService>
先來說說這個Func<string, IDemoService>里面的string和IDemoService都分別代表什么。
string 毫無疑問就是我們上面說到的別名
IDemoService 這個就是我們要用的Service
核心在于,factory參數是IServiceProvider類型的!所以我們可以根據這個factory去找到我們前面注冊的實現類。這樣解釋一下,是不是就清晰了呢?
然后再來看看在控制器上面怎么用。
private IDemoService _serviceA;private IDemoService _serviceB;
private readonly Func<string, IDemoService> _serviceAccessor;
public ValuesController(Func<string, IDemoService> serviceAccessor){ ? ?this._serviceAccessor = serviceAccessor;_serviceA = _serviceAccessor("ServiceA");_serviceB = _serviceAccessor("ServiceB"); }
// GET api/values
[HttpGet]
public string Get(){ ? ?
? return $"{_serviceA.Get()}-{_serviceB.Get()}"; }
最后看看結果是不是和我們的預期一樣。
結果與預期一致。
總結
一對一,或許是最好的方法,也是最為理想的,這樣能避開很多不必要的問題。但是現實中總會出現特殊情況,面對這些特殊情況,我們也是需要能夠重容的面對。
原文地址:http://www.cnblogs.com/catcher1994/p/handle-multi-implementations-with-same-interface-in-dotnet-core.html
.NET社區新聞,深度好文,歡迎訪問公眾號文章匯總 http://www.csharpkit.com
總結
以上是生活随笔為你收集整理的在.NET Core中处理一个接口多个不同实现的依赖注入问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微软高管解读财报:努力创新云基础架构
- 下一篇: 你可能不知道的.Net Core Con