欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

ASP.NET Core如何注入多個(gè)服務(wù)實(shí)現(xiàn)類(lèi)

 更新時(shí)間:2021年09月09日 11:35:32   作者:東邪獨(dú)孤  
這篇文章主要介紹了ASP.NET Core如何注入多個(gè)服務(wù)實(shí)現(xiàn)類(lèi)的相關(guān)資料,需要的朋友可以參考下面文章的具體內(nèi)容

前言:

依賴(lài)注入在 ASP.NET Core 中起中很重要的作用,也是一種高大上的編程思想,它的總體原則就是:俺要啥,你就給俺送啥過(guò)來(lái)。服務(wù)類(lèi)型的實(shí)例轉(zhuǎn)由容器自動(dòng)管理,無(wú)需我們?cè)诖a中顯式處理。

因此,有了依賴(lài)注入后,你的編程思維就得變一變了。在過(guò)去,許多功能性的類(lèi)型(比如一個(gè)加密解密的類(lèi)),我們都喜歡將其定義為靜態(tài)(static),而有了依賴(lài)注入,你就要避免使用靜態(tài)類(lèi)型,應(yīng)該交由服務(wù)容器幫你管理,只要你用好了,你會(huì)發(fā)現(xiàn)依賴(lài)注入是很方便的。

依賴(lài)注入的初級(jí)玩法,也是比較標(biāo)準(zhǔn)的玩法,此種玩法有兩種模式:

  1. 十代單傳模式:一個(gè)接口對(duì)應(yīng)一個(gè)類(lèi),比如先定義接口 IA、IB,隨后,類(lèi)A實(shí)現(xiàn) IA,類(lèi)B 實(shí)現(xiàn) IB。一對(duì)一。也可以是抽象類(lèi)(或基類(lèi))E,然后 F 繼承 E 類(lèi)。
  2. 斷子絕孫模式:直接就寫(xiě)一個(gè)類(lèi),不考慮派生,直接就添加到服務(wù)容器中。

來(lái),看個(gè)例子。

1、定義個(gè)接口

    public interface IPlayGame
    {
        void Play();
    }


然后,寫(xiě)一個(gè)類(lèi)來(lái)實(shí)現(xiàn)它。

    public class NBPlayGame : IPlayGame
    {
        public void Play()
        {
            Console.WriteLine("全民打麻藥。");
        }
    }

我們知道,所謂服務(wù)類(lèi),其實(shí)就是普通類(lèi),這些類(lèi)一般用于完成某些功能,比如計(jì)算 MD5 值。接著呢,還記得 Startup 類(lèi)有個(gè) ConfigureServices 方法吧,對(duì),就在這廝里面把我們剛剛那個(gè)服務(wù)進(jìn)行注冊(cè)(就是添加到 ServiceCollection 集合中)。

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddTransient<IPlayGame, NBPlayGame>();
        }


添加的時(shí)候很簡(jiǎn)單,類(lèi)型一對(duì)一,IPlayGame 接口與 NBPlayGame 類(lèi)對(duì)應(yīng)。添加時(shí)有三種方法你可以調(diào)用,實(shí)際上對(duì)應(yīng)著,服務(wù)類(lèi)在容器中的生命周期。

  • AddSingleton:單個(gè)實(shí)例,這是壽命最長(zhǎng)的,與天同壽。整個(gè)應(yīng)用程序中僅用一個(gè)實(shí)例。
  • AddTransient:這個(gè)是最短命的,可能是天天晚上加班熬夜,死得很快。此種情況下,服務(wù)類(lèi)的實(shí)例是用的時(shí)候創(chuàng)建,用完后直接銷(xiāo)毀。
  • AddScoped:這個(gè)比較難理解。它的生命周期在單個(gè)請(qǐng)求內(nèi),包括客戶(hù)端與服務(wù)器之間隨后產(chǎn)生的子請(qǐng)求,反正只要請(qǐng)求的會(huì)話(huà)結(jié)束了,就會(huì)清理。

2、注入服務(wù)

比如在中間件,在控制器,或者在其他服務(wù)類(lèi)的構(gòu)造函數(shù)上(中間件是在 Invoke / InvokeAsync 方法上)進(jìn)行實(shí)例接收。

現(xiàn)在來(lái)用一下,寫(xiě)一個(gè)中間件。

    public class TestMiddleware
    {
        public TestMiddleware(RequestDelegate next) { }

        public Task InvokeAsync(HttpContext context, IPlayGame game)
        {
            game.Play();
            return Task.CompletedTask;
        }
    }

已注冊(cè)的服務(wù)會(huì)注入到 InvokeAsync 方法的參數(shù)中。注意第一個(gè)參數(shù)是 HttpContext,這是必須參數(shù),后面的是注入的參數(shù)。

最后,在 Startup 類(lèi)的 Configure 方法中就可以 use 這個(gè)中間件了。

        public void Configure(IApplicationBuilder app)
        {
            app.UseMiddleware<TestMiddleware>();
        }
 

運(yùn)行后,Play 方法調(diào)用,在控制臺(tái)中輸出以下結(jié)果

 3、功能類(lèi)

 也稱(chēng)“斷子絕孫”模式,不使用接口規(guī)范,直接寫(xiě)功能類(lèi)。

    public class DoSomething
    {
        public string GetMessage() => "你好,剛才 Boss 找你。";
    }

注冊(cè)服務(wù)時(shí)更簡(jiǎn)單。

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddScoped<DoSomething>();
        }

在 Configure 方法中進(jìn)行注入。

        public void Configure(IApplicationBuilder app, DoSomething thing)
        {
            Console.WriteLine(thing.GetMessage());
        }


運(yùn)行后,輸出結(jié)果如下

 

 在容器中,使用 ServiceDescriptor 類(lèi)來(lái)存儲(chǔ)服務(wù)類(lèi)型相關(guān)的信息。其中,ServiceType 表示的是服務(wù)的類(lèi)型,如果服務(wù)是有接口與實(shí)現(xiàn)類(lèi)的,那么這個(gè)屬性指的是接口的類(lèi)型,實(shí)現(xiàn)類(lèi)的類(lèi)型信息由 ImplementationType 屬性存儲(chǔ)。如果沒(méi)有接口,直接只定義類(lèi)型,那么這個(gè)類(lèi)型的信息就存到 ServiceType 屬性上,ImplementationType 屬性不使用。

上面這些例子中,ServiceType 是 IPlayGame 接口相關(guān)信息,ImplementationType 是 NBPlayGame 類(lèi)的信息。如果像上面 DoSomething 類(lèi)的情況,則 ServiceType 為 DoSomething 相關(guān)的信息,ImplementationType 為空。

 4、高級(jí)類(lèi)

接下來(lái),咱們看高級(jí)玩法。

定義一個(gè)接口。

    public interface IDemoService
    {
        string Version { get; }
        void Run();
    }


然后,有兩個(gè)類(lèi)實(shí)現(xiàn)這個(gè)接口。

    public class DemoService1 : IDemoService
    {
        public string Version => "v1";

        public void Run()
        {
            Console.WriteLine("第一個(gè)服務(wù)實(shí)現(xiàn)類(lèi)。");
        }
    }

    public class DemoService2 : IDemoService
    {
        public string Version => "v2";

        public void Run()
        {
            Console.WriteLine("第二個(gè)服務(wù)實(shí)現(xiàn)類(lèi)。");
        }
    }

然后,我們注冊(cè)服務(wù)。

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddTransient<IDemoService, DemoService1>();
            services.AddTransient<IDemoService, DemoService2>();
        }


然后我們照例,接收注入,咱們依舊使用中間件的方法參數(shù)接收。

    public class DemoMiddleware
    {
        public DemoMiddleware(RequestDelegate next)
        {
            // 由于程序約定,此構(gòu)造函數(shù)必須提供。
        }

        public async Task InvokeAsync(HttpContext context, IDemoService sv)
        {
            await context.Response.WriteAsync(sv.Version);
        }
    }

然后,在 Startup.Configure 方法中使用該中間件。

        public void Configure(IApplicationBuilder app, DoSomething thing)
        {
            app.UseMiddleware<DemoMiddleware>();
        }


運(yùn)行之后,你發(fā)現(xiàn)問(wèn)題了,看看輸出。

 

 出事了,參數(shù)僅能接收到最后注冊(cè)的實(shí)現(xiàn)類(lèi)型實(shí)例,也就是 DemoService2 類(lèi)。所以就看到網(wǎng)上有不少朋友發(fā)貼問(wèn)了,.NET Core 是不是不支持多個(gè)服務(wù)實(shí)現(xiàn)類(lèi)的注入?這難倒了很多人。

實(shí)話(huà)告訴你,Core Core 兄是支持注入多個(gè)實(shí)現(xiàn)類(lèi)的實(shí)例的。

下面,老周介紹兩種解決方法(其實(shí)有三種,還有一種不太好弄,尤其是你對(duì) Core 兄不熟的時(shí)候,所以我說(shuō)兩種,基本夠用)。

方法一、接收 IServiceProvider 類(lèi)型的注入。

        public async Task InvokeAsync(HttpContext context, IServiceProvider provider)
        {
            StringBuilder sb = new StringBuilder();
            foreach (var sv in provider.GetServices<IDemoService>())
            {
                sb.Append($"{sv.Version}<br/>");
            }
            await context.Response.WriteAsync(sb.ToString());
        }

只要能接收到 IServiceProvider 所引用的實(shí)例,就能通過(guò) GetServices 方法獲取多個(gè)服務(wù)實(shí)例。

方法二,這種方法老周很推薦,更簡(jiǎn)單,直接注入 IEnumerable<T> 類(lèi)型,本例中就是 IEnumerable<IDemoService>。

        public async Task InvokeAsync(HttpContext context, IEnumerable<IDemoService> svs)
        {
            StringBuilder sb = new StringBuilder();
            foreach (var sv in svs)
            {
                sb.Append($"{sv.Version}<br/>");
            }
            await context.Response.WriteAsync(sb.ToString());
        }

IEnumerable<T> 的妙處就是可以 foreach ,這樣你也能訪問(wèn)多個(gè)實(shí)例,而且必要時(shí)還可以聯(lián)合 LINQ 一起耍。

運(yùn)行結(jié)果如下。

 

到此這篇關(guān)于ASP.NET Core如何注入多個(gè)服務(wù)實(shí)現(xiàn)類(lèi)的文章就介紹到這了,更多相關(guān)ASP.NET Core何注多個(gè)服務(wù)實(shí)現(xiàn)類(lèi)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 深入分析XmlSerializer對(duì)象的Xml序列化與反序列化的示例詳解

    深入分析XmlSerializer對(duì)象的Xml序列化與反序列化的示例詳解

    本篇文章是對(duì)XmlSerializer 對(duì)象的Xml序列化與反序列化的應(yīng)用進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • .NET?Core?中對(duì)象池?Object?Pool的使用

    .NET?Core?中對(duì)象池?Object?Pool的使用

    這篇文章主要介紹了?.NET?Core?中對(duì)象池?Object?Pool的使用,對(duì)象池簡(jiǎn)單來(lái)說(shuō)就是一種為對(duì)象提供可復(fù)用能力的軟件設(shè)計(jì)思路,對(duì)象池最常用的場(chǎng)景是游戲設(shè)計(jì),因?yàn)樵谟螒蛑写罅看嬖谥蓮?fù)用的對(duì)象,源源不斷的子彈出現(xiàn)并不是循環(huán)再生的,下面一起進(jìn)入文章了解具體內(nèi)容吧
    2021-11-11
  • asp.net core使用DevExtreme20將int列轉(zhuǎn)為checkbox方法示例

    asp.net core使用DevExtreme20將int列轉(zhuǎn)為checkbox方法示例

    這篇文章主要為大家介紹了asp.net core使用DevExtreme20將int列轉(zhuǎn)為checkbox方法示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08
  • upload上傳單張圖片

    upload上傳單張圖片

    這篇文章主要介紹了upload上傳單張圖片的代碼,需要的朋友可以參考下。
    2015-07-07
  • .Net實(shí)現(xiàn)圖片裁剪圖片縮放及圖片加水印詳解

    .Net實(shí)現(xiàn)圖片裁剪圖片縮放及圖片加水印詳解

    這篇文章主要為大家介紹了.Net實(shí)現(xiàn)圖片裁剪圖片縮放及圖片加水印實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09
  • .Net Core 之AutoFac的使用

    .Net Core 之AutoFac的使用

    本文簡(jiǎn)單介紹了AutoFac的基本使用以及在asp .net core中的應(yīng)用,文中通過(guò)代碼講解相關(guān)知識(shí)非常的詳細(xì),對(duì)大家的學(xué)習(xí)或工作都很有幫助,感興趣的小伙伴可以參考一下這篇文章
    2021-09-09
  • 使用.NET6實(shí)現(xiàn)動(dòng)態(tài)API

    使用.NET6實(shí)現(xiàn)動(dòng)態(tài)API

    本文詳細(xì)講解了使用.NET6實(shí)現(xiàn)動(dòng)態(tài)API,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-12-12
  • 在NET?Core?中獲取?CPU?使用率

    在NET?Core?中獲取?CPU?使用率

    這篇文章我們分享一種如何在?.NETCore?中獲取?CPU使用率的方法,?它所報(bào)告的這個(gè)值和?任務(wù)管理器?中報(bào)告的?CPU?使用值?差不多是一致的,下面來(lái)看看文中的具體詳細(xì)介紹吧
    2022-01-01
  • ASP.NET Core WebSocket集群實(shí)現(xiàn)思路詳解

    ASP.NET Core WebSocket集群實(shí)現(xiàn)思路詳解

    這篇文章主要為大家介紹了ASP.NET Core WebSocket集群實(shí)現(xiàn)思路詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • .Net性能調(diào)優(yōu)-ArrayPool詳情

    .Net性能調(diào)優(yōu)-ArrayPool詳情

    ArrayPool具有高性能 托管 數(shù)組緩沖池,可重復(fù)使用,用 租用 空間的方式代替 重新分配 數(shù)組空間的行為的特點(diǎn)及可以在頻繁創(chuàng)建和銷(xiāo)毀數(shù)組的情況下 提高性能 ,減少垃圾回收器的壓力的優(yōu)點(diǎn),下面文章內(nèi)容將詳細(xì)對(duì)其做介紹,需要的朋友可以參考一下
    2021-09-09

最新評(píng)論