日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > asp.net >内容正文

asp.net

.NET Core中的一个接口多种实现的依赖注入与动态选择

發(fā)布時(shí)間:2023/12/4 asp.net 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 .NET Core中的一个接口多种实现的依赖注入与动态选择 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

最近有個(gè)需求就是一個(gè)抽象倉(cāng)儲(chǔ)層接口方法需要SqlServer以及Oracle兩種實(shí)現(xiàn)方式,為了靈活我在依賴注入的時(shí)候把這兩種實(shí)現(xiàn)都給注入進(jìn)了依賴注入容器中,但是在服務(wù)調(diào)用的時(shí)候總是獲取到最后注入的那個(gè)方法的實(shí)現(xiàn),這時(shí)候就在想能不能實(shí)現(xiàn)動(dòng)態(tài)的選擇使用哪種實(shí)現(xiàn)呢?如果可以的話那么我只需要在配置文件中進(jìn)行相應(yīng)的配置即可獲取到正確的實(shí)現(xiàn)方法的調(diào)用,這樣的話豈不快哉!今天我們就來一起探討下實(shí)現(xiàn)這種需求的幾種實(shí)現(xiàn)方式吧。

作者:依樂祝
原文地址:https://www.cnblogs.com/yilezhu/p/10236163.html

代碼演示

在開始實(shí)現(xiàn)的方式之前,我們先模擬下代碼。由于真實(shí)系統(tǒng)的結(jié)構(gòu)比較復(fù)雜,所以這里我就單獨(dú)建一個(gè)類似的項(xiàng)目結(jié)構(gòu)代碼。項(xiàng)目如下圖所示:

接下來我來詳細(xì)說下上面的結(jié)果作用及代碼。

  • MultiImpDemo.I 這個(gè)項(xiàng)目是接口項(xiàng)目,里面有一個(gè)簡(jiǎn)單的接口定義ISayHello,代碼如下:

    ? ?public interface ISayHello{ ? ? ? ?string Talk();}

    很簡(jiǎn)單,就一個(gè)模擬講話的方法。

  • MultiImpDemo.A 這個(gè)類庫(kù)項(xiàng)目是接口的一種實(shí)現(xiàn)方式,里面有一個(gè)SayHello類用來實(shí)現(xiàn)ISayHello接口,代碼如下:

  • MultiImpDemo.B 這個(gè)類庫(kù)項(xiàng)目是接口的另一種實(shí)現(xiàn)方式,里面也有一個(gè)SayHello類用來實(shí)現(xiàn)ISayHello接口,代碼如下:


  • MultiImpDemo.Show 這個(gè)就是用來顯示我們模擬效果的API項(xiàng)目,首選我們?cè)贑onfigureServices中加入如下的代碼來進(jìn)行上述兩種實(shí)現(xiàn)方式的注入:

  • 在api實(shí)現(xiàn)里面獲取服務(wù)并進(jìn)行模擬調(diào)用:


  • 代碼很簡(jiǎn)單對(duì)不對(duì)?你應(yīng)該看的懂吧,這時(shí)候我們運(yùn)行起來項(xiàng)目,然后訪問API'api/values'這個(gè)接口,結(jié)果總是顯示如下的結(jié)果:

    兩種需求對(duì)應(yīng)兩種實(shí)現(xiàn)

    這里有兩種業(yè)務(wù)需求!第一種業(yè)務(wù)中只需要對(duì)其中一種實(shí)現(xiàn)方式進(jìn)行調(diào)用,如:業(yè)務(wù)需要SqlServer數(shù)據(jù)庫(kù)的實(shí)現(xiàn)就行了。第二種是業(yè)務(wù)中對(duì)這兩種實(shí)現(xiàn)方式都有用到,如:業(yè)務(wù)急需要用到Oracle的數(shù)據(jù)庫(kù)實(shí)現(xiàn)同時(shí)也有用到SqlServer的數(shù)據(jù)庫(kù)實(shí)現(xiàn),需要同時(shí)往這兩個(gè)數(shù)據(jù)庫(kù)中插入相同的數(shù)據(jù)。下面分別對(duì)這兩種需求進(jìn)行解決。

    業(yè)務(wù)中對(duì)這兩種實(shí)現(xiàn)方式都有用到

    針對(duì)這種情況有如下兩種實(shí)現(xiàn)方式:

  • 第二種實(shí)現(xiàn)方式

    其實(shí),在ASP.NET Core中,當(dāng)你對(duì)一個(gè)接口注冊(cè)了多個(gè)實(shí)現(xiàn)的時(shí)候,構(gòu)造函數(shù)是可以注入一個(gè)該接口集合的,這個(gè)集合里是所有注冊(cè)過的實(shí)現(xiàn)。

    下面我們先改造下ConfigureServices,分別注入下這兩種實(shí)現(xiàn)

    接著繼續(xù)改造下注入的方式,這里我們直接注入IEnumerable<ISayHello>如下代碼所示:

    然后運(yùn)行起來看下效果吧

  • 利用AddTransient的擴(kuò)展方法public static IServiceCollection AddTransient<TService>(this IServiceCollection services, Func<IServiceProvider, TService> implementationFactory) where TService : class;然后根據(jù)我們的配置的實(shí)現(xiàn)來進(jìn)行服務(wù)實(shí)現(xiàn)的獲取。下面就讓我們利用代碼來實(shí)現(xiàn)一番吧:

    然后我們具體調(diào)用的依賴注入的方式需要變化一下:


    然后運(yùn)行看下效果吧:

    可以看到A跟B的實(shí)現(xiàn)都獲取到了!效果實(shí)現(xiàn)!

  • 業(yè)務(wù)只需要對(duì)其中一種實(shí)現(xiàn)方式的調(diào)用

    這時(shí)候我們可以根據(jù)我們預(yù)設(shè)的配置來動(dòng)態(tài)獲取我們所需要的實(shí)現(xiàn)。這段話說的我自己都感覺拗口。話不多少,開魯吧!這里我將介紹三種實(shí)現(xiàn)方式。

  • 根據(jù)我們的配置文件中設(shè)置的key來進(jìn)行動(dòng)態(tài)的注入。

    這種方式實(shí)現(xiàn)之前首先得進(jìn)行相應(yīng)的配置,如下所示:

    ?"CommonSettings": { ? ?"ImplementAssembly": "MultiImpDemo.A"}

    然后在注入的時(shí)候根據(jù)配置進(jìn)行動(dòng)態(tài)的進(jìn)行注入:

    services.AddTransient<ISayHello, A.SayHello>(); ? ? ? ? ? ?services.AddTransient<ISayHello, B.SayHello>();

    然后在服務(wù)調(diào)用的時(shí)候稍作修改:

    OK,到這里運(yùn)行一下看下效果吧!然后改下配置文件再看下效果!

  • 第二種實(shí)現(xiàn)方式,即接口參數(shù)的方式這樣可以避免上個(gè)方法中反射所帶來的性能損耗。

    這里我們改造下接口,接口中加入一個(gè)程序集的屬性,如下所示:

    public interface ISayHello{ ? ? ? ?string ImplementAssemblyName { get; } ? ? ? ?string Talk();}

    對(duì)應(yīng)的A跟B中的實(shí)現(xiàn)代碼也要少做調(diào)整:

    A:

    public string ImplementAssemblyName => "MultiImpDemo.A"; ? ? ? ?
    public string Talk(){ ? ? ? ? ? ?return "Talk from A.SayHello";}

    B:

    public string ImplementAssemblyName => "MultiImpDemo.B"; ? ? ?
    ?public string Talk(){ ? ? ? ? ? ?return "Talk from B.SayHello";}

    然后,在實(shí)現(xiàn)方法調(diào)用的時(shí)候稍微修改下:

    效果自己運(yùn)行下看下吧!

  • 第三種實(shí)現(xiàn)是根據(jù)配置進(jìn)行動(dòng)態(tài)的注冊(cè)

    首先修改下ConfigureServices方法:

  • 這樣的話就會(huì)根據(jù)我們的配置文件來進(jìn)行動(dòng)態(tài)的注冊(cè),然后我們像往常一樣進(jìn)行服務(wù)的調(diào)取即可:

    ?private readonly ISayHello _sayHello; ? ? ? ?public ValuesController(ISayHello sayHello) ? ? ? ?{_sayHello = sayHello;} ? ? ? ?// GET api/values[HttpGet] ? ? ? ?public ActionResult<IEnumerable<string>> Get(){ ? ? ? ? ? ?return new string[] { _sayHello.Talk() };}

    運(yùn)行即可得到我們想要的效果!

  • 總結(jié)

    本文從具體的業(yè)務(wù)需求入手,根據(jù)需求來或動(dòng)態(tài)的進(jìn)行對(duì)應(yīng)服務(wù)的獲取,或同時(shí)使用兩個(gè)不同的實(shí)現(xiàn)!希望對(duì)您有所幫助!如果您有更多的實(shí)現(xiàn)方法可以在下方留言,或者加入.NET Core實(shí)戰(zhàn)千人群跟637326624大伙進(jìn)行交流,最后感謝您的閱讀!



    總結(jié)

    以上是生活随笔為你收集整理的.NET Core中的一个接口多种实现的依赖注入与动态选择的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。