<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          .NET Core 依賴注入 使用技巧

          共 4164字,需瀏覽 9分鐘

           ·

          2022-05-16 12:26


          前言

          ?

          .NET Core 在使用IOC后,我們不必再浪費(fèi)精力在管理實(shí)例的生命周期上,交給IOC代替我們管理,減少我們成噸的代碼,面向接口編程更是靈活到了極致,而IOC的三種生命周期應(yīng)該怎么去使用呢,Transient(瞬態(tài))、Scoped(作用域)、Singleton(單例)。


          Transient(瞬態(tài))


          這個(gè)沒(méi)什么好說(shuō)的,就是每次注入的時(shí)候,容器自動(dòng) new 一個(gè)實(shí)例,用完就丟;

          Scoped(作用域)

          以Web來(lái)說(shuō),作用域的生命周期就是當(dāng)次請(qǐng)求,請(qǐng)求開(kāi)始后的第一次注入,就是它生命的開(kāi)始,直到請(qǐng)求結(jié)束;

          我個(gè)人常用來(lái)減少數(shù)據(jù)獲取,提升請(qǐng)求響應(yīng),舉一個(gè)例子:A服務(wù)是獲取全國(guó)地級(jí)市信息的,以作用域的方式注冊(cè)到IOC容器中,B、C、D 都注入了A服務(wù)并使用了它;一個(gè)業(yè)務(wù)接口,剛好涉及到了B、C、D,當(dāng)接口被調(diào)用,代碼執(zhí)行到了B,第一次調(diào)用了 A 服務(wù)請(qǐng)求數(shù)據(jù)庫(kù)獲取了全國(guó)地級(jí)市數(shù)據(jù);然后執(zhí)行到了C,又一次使用了A服務(wù)獲取了數(shù)據(jù),最后D;一個(gè)請(qǐng)求下來(lái),A被使用了3次,獲取了3個(gè)同樣的數(shù)據(jù)結(jié)果,這完全是在浪費(fèi)資源;

          public?class?AService
          {
          ????public?async?CityData?GetCityDataAsync()
          ????{
          ????????return?await?GetDatasFromApi();
          ????}
          }

          public?class?BService
          {
          ????private?readonly?AService?_aService;

          ????public?BService(AService?aService)
          ????{
          ????????_aService?=?aService;
          ????}
          ????
          ????public?async?Task?Execute()
          ????{
          ????????await?_aService.GetCityDataAsync();
          ????}
          }

          public?class?CService
          {
          ????private?readonly?AService?_aService;

          ????public?CService(AService?aService)
          ????{
          ????????_aService?=?aService;
          ????}

          ????public?async?Task?Execute()
          ????{
          ????????await?_aService.GetCityDataAsync();
          ????}
          }

          public?class?DService
          {
          ????private?readonly?AService?_aService;

          ????public?DService(AService?aService)
          ????{
          ????????_aService?=?aService;
          ????}

          ????public?async?Task?Execute()
          ????{
          ????????await?_aService.GetCityDataAsync();
          ????}
          }

          不是可以定義一個(gè)變量,請(qǐng)求數(shù)據(jù)前先判斷這個(gè)變量有沒(méi)有值,沒(méi)有就去獲取數(shù)據(jù),給它賦值,下次再調(diào)用的時(shí)候,直接返回這個(gè)變量的數(shù)據(jù),這樣不管這個(gè)服務(wù)被調(diào)用多少次,它也只是調(diào)用了一次數(shù)據(jù)庫(kù),大大節(jié)省了資源。

          public?class?AService
          {
          ????private?List?cityDatas;
          ????????
          ????public?async?List?GetCityDataAsync()
          ????{
          ????????if(cityDatas?==?null||?!cityDatas.Any())
          ????????{
          ????????????cityDatas?=?await?GetDatasFromApi();
          ????????}
          ????????
          ????????return?cityDatas;
          ????}
          }

          有人可能說(shuō)會(huì)說(shuō)了,不就是多調(diào)用幾次數(shù)據(jù)庫(kù),現(xiàn)在服務(wù)器的性能這么好,不在乎這一點(diǎn)的資源;確實(shí),如果只是多調(diào)用幾次數(shù)據(jù)庫(kù),對(duì)于一些小系統(tǒng)來(lái)說(shuō),跟撓癢癢一樣,那這里的調(diào)用數(shù)據(jù)庫(kù)換成調(diào)用 WebApi 呢?

          如果還是調(diào)用第三方的 API 呢?一次Http請(qǐng)求,不往大的說(shuō),從請(qǐng)求到獲取到數(shù)據(jù),花個(gè)100ms很正常吧(網(wǎng)絡(luò)非常好的情況當(dāng)我沒(méi)說(shuō)),那這個(gè)接口不需要多,調(diào)用10次就1s了,還沒(méi)算上其它業(yè)務(wù)邏輯的耗時(shí)呢,如果還需要調(diào)用其它的api,那響應(yīng)時(shí)間就更長(zhǎng)咯,難道你讓用戶打開(kāi)一個(gè)頁(yè)面,或者點(diǎn)擊一個(gè)按鈕,需要等上兩三秒才有響應(yīng)嗎,這樣的用戶體驗(yàn)就非常糟糕了。

          Singleton(單例)

          來(lái)自依賴關(guān)系注入容器的服務(wù)實(shí)現(xiàn)的每一個(gè)后續(xù)請(qǐng)求都使用同一個(gè)實(shí)例。如果應(yīng)用需要單一實(shí)例行為,則允許服務(wù)容器管理服務(wù)的生存期。必須是線程安全的,并且通常在無(wú)狀態(tài)服務(wù)中使用。

          在單例中,不要直接注入作用域的服務(wù),這會(huì)引起很多莫名其妙的錯(cuò)誤(經(jīng)過(guò)評(píng)論區(qū)大佬的指正,修正這個(gè)不恰當(dāng)?shù)挠迷~,這里引用大佬的一段話) 單例中引用Scoped,Scoped就會(huì)提升為單例,這就很容易發(fā)生錯(cuò)誤,一定要使用的話,就自己創(chuàng)建,自己管理它的生命周期:

          public?class?Scope
          {
          ????private?readonly?IServiceScopeFactory?_serviceScopeFactory;
          ????public?Scope(IServiceScopeFactory?serviceScopeFactory)
          ????{
          ????????_serviceScopeFactory?=?serviceScopeFactory;
          ????}

          ????public?async?Task?CreateScope()
          ????{
          ????????using?var?scope?=?_serviceScopeFactory.CreateScope();

          ????????var?service?=?scope.ServiceProvider.GetRequiredService();
          ????}
          }

          ActivatorUtilities

          有些情況下,例如當(dāng)你不想把使用次數(shù)極低的類注冊(cè)到容器中,或者這個(gè)類的構(gòu)造函數(shù)需要傳入一些參數(shù),但是又需要用到容器中的服務(wù)的時(shí)候,你可以使用 ActivatorUtilities 中的 CreateInstance 去創(chuàng)建它,它會(huì)自動(dòng)給構(gòu)造函數(shù)注入所需的服務(wù),并且還可以給構(gòu)造函數(shù)傳參,滿足上面所說(shuō)情況的需求。

          public?class?TestTask?:?ITask
          {
          ????private?readonly?IServiceScopeFactory?_serviceScopeFactory;

          ????private?readonly?IRabbitMQService?_rabbitMQService;

          ????private?readonly?string?_name;

          ????public?TestTask(IServiceScopeFactory?serviceScopeFactory,?IRabbitMQService?rabbitMQService,?string?name)
          ????{
          ????????_serviceScopeFactory?=?serviceScopeFactory;
          ????????_rabbitMQService?=?rabbitMQService;
          ????????_name?=?name;
          ????}

          ????///?
          ????///?
          ????///?

          ????///?
          ????///?
          ????///?
          ????public?async?Task?Execute(CancellationToken?cancellationToken)
          ????{
          ????????try
          ????????{
          ????????????using?var?scope?=?_serviceScopeFactory.CreateScope();

          ????????????var?executionService?=?scope.ServiceProvider.GetService();

          ????????????if?(executionService?!=?null)
          ????????????{
          ????????????????await?_rabbitMQService.RabbitMQReceiveService.SingleAsync(executionService.ExecuteAsync);
          ????????????}
          ????????}
          ????????catch?(Exception?err)
          ????????{

          ????????????Console.WriteLine(err.Message);
          ????????}
          ????}
          }

          使用 ActivatorUtilities 創(chuàng)建:

          var?testTask?=?ActivatorUtilities.CreateInstance(serviceProvider,?"test");
          await?testTask.Execute(new?CancellationToken());

          寫在最后

          Bootstrap Blazor 官網(wǎng)地址:https://www.blazor.zone

          希望大佬們看到這篇文章,能給項(xiàng)目點(diǎn)個(gè)star支持下,感謝各位!

          Star流程:

          1、訪問(wèn)點(diǎn)擊項(xiàng)目鏈接:https://gitee.com/LongbowEnterprise/BootstrapBlazor

          2、點(diǎn)擊star,如下圖,即可完成star,關(guān)注項(xiàng)目不迷路:

          另外還有兩個(gè)GVP項(xiàng)目,大佬們方便的話也點(diǎn)下star唄,非常感謝:

          BootstrapAdmin:https://gitee.com/LongbowEnterprise/BootstrapAdmin

          SliderCaptcha :https://gitee.com/LongbowEnterprise/SliderCaptcha

          轉(zhuǎn)自:一事冇誠(chéng)

          鏈接:cnblogs.com/ysmc/p/16240534.html


          瀏覽 59
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  日日插,日日操 | 蜜臀日韩免费 | 成人影音a片 | 干欧美女人 | 97超碰在线免费 |