Blazor University (52)依賴注入 —— 擁有多個依賴項:正確的方式

原文鏈接:https://blazor-university.com/dependency-injection/component-scoped-dependencies/owning-multiple-dependencies-the-right-way/

擁有多個依賴項:正確的方式

在上一節[1]中,我們看到了將多個擁有的依賴項注入組件的錯誤方法。本節將演示解決問題的正確方法。

如前所述,OwningComponentBase<T> 類組件將創建自己的依賴容器并在該容器中解析 T 的實例,因此 T 的實例對于我們的組件是私有的。

如果我們需要我們的組件私有地擁有多種依賴類型的實例,那么我們必須做更多的工作。為此,我們需要使用非泛型 OwningComponentBase 類。與通用版本一樣,此組件將創建自己的依賴容器,該容器將在組件的生命周期內存在。但是,它不會為我們實際解析任何依賴項,而是讓我們訪問其依賴項容器,以便我們可以解析我們需要的任何類型的實例。

示例

源代碼[2]

首先,創建一個新的 Blazor 應用程序。然后,就像我們之前所做的那樣,我們將創建一些可以注入的類,這些類將使用狀態成員來跟蹤已創建的類實例的數量。

創建以下接口

public?interface?IOwnedDependency1
{public?int?InstanceNumber?{?get;?}
}public?interface?IOwnedDependency2
{public?int?InstanceNumber?{?get;?}
}

然后創建實現這些接口的類。我將只顯示第一類的代碼,第二類將是相同的。

public?class?OwnedDependency1?:?IOwnedDependency1
{private?static?volatile?int?PreviousInstanceNumber;public?int?InstanceNumber?{?get;?}public?OwnedDependency1(){InstanceNumber?=System.Threading.Interlocked.Increment(ref?PreviousInstanceNumber);}
}

將接口 + 它們的實現類注冊為 Scoped(如果需要提醒您,請參閱比較依賴范圍[3])。

接下來,編輯 Index.razor 頁面,以便我們應用程序的用戶可以通過單擊復選框來切換組件。

@page?"/"<input?id="show-component"?type=checkbox?@bind=ShowComponent?/>
<label?for="show-component">Show?component</label>@if?(ShowComponent)
{<MyOwningComponent?/>
}@code
{bool?ShowComponent?=?false;
}

ShowComponenttrue 時,我們的標記將創建 MyOwningComponent 的一個實例并渲染它。接下來,我們將創建 MyOwningComponent

OwningComponentBase

Shared 文件夾中,創建一個名為 MyOwningComponent 的新 Razor 組件。我們將從 OwningComponentBase 中派生此組件。

@inherits?OwningComponentBase

然后創建一些類字段來保存依賴項。

@code
{private?IOwnedDependency1?OwnedDependency1;private?IOwnedDependency2?OwnedDependency2;
}

解決擁有的依賴關系

OwningComponentBase 創建的私有依賴性容器通過其ScopedServices 屬性提供給我們。

protected?IServiceProvider?ScopedServices?{?get;?}

我們可以使用這個 IServiceProvider 來解析組件所擁有的私有依賴容器中的依賴實例。

@inherits?OwningComponentBase
@using?Microsoft.Extensions.DependencyInjection<div>OwnedDependency1.InstanceNumber?=?@OwnedDependency1.InstanceNumber
</div>
<div>OwnedDependency2.InstanceNumber?=?@OwnedDependency2.InstanceNumber
</div>@code
{private?IOwnedDependency1?OwnedDependency1;private?IOwnedDependency2?OwnedDependency2;protected?override?void?OnInitialized(){OwnedDependency1?=ScopedServices.GetService<IOwnedDependency1>();OwnedDependency2?=ScopedServices.GetService<IOwnedDependency2>();}
}
  • 第 1 行

    OwningComponentBase 繼承來給我們自己的私有依賴容器。

  • 第 2 行

    使用 DependencyInjection 命名空間,因此我們可以在 IServiceProvider 上使用 GetService<T> 擴展方法。

  • 第 19 & 21 行

    使用 OwningComponentBase.ScopedServices 屬性來解析組件所需的依賴項實例。

  • 第 6 & 9 行

    顯示為我們創建的依賴項的實例號。

運行示例

如果我們運行示例應用并勾選復選框,我們將看到以下輸出。

  • OwnedDependency1.InstanceNumber = 1

  • OwnedDependency2.InstanceNumber = 1

取消勾選該復選框以允許刪除我們的組件,然后再次勾選該復選框以讓 Blazor 創建 MyOwningComponent 的新實例。渲染輸出現在應該如下所示。

  • OwnedDependency1.InstanceNumber = 2

  • OwnedDependency2.InstanceNumber = 2

這表明,每次創建組件時,我們在組件的 OnInitialized 方法中解析的兩個依賴項都是新的實例。

依賴生命周期

OwningComponentBase 類實現 IDisposable 接口。當從OwningComponentBase 派生的任何組件不再呈現時,Blazor 將在 OwningComponentBase 上執行 Dispose 方法。

組件上的 Dispose 方法將對其擁有的私有依賴項容器調用Dispose。反過來,該容器創建的任何實現 IDisposable 的對象實例也將執行其 Dispose 方法。

要演示這種行為,請對應用程序進行以下更改。

首先,在我們的組件上重寫 Dispose(bool isDisposing),并讓它在被釋放時輸出日志。

public?void?Dispose()
{System.Diagnostics.Debug.WriteLine("Disposing?"?+?GetType().Name);
}

然后,對于我們的每個依賴類(OwnedDependency1OwnedDependency2),讓它們實現 IDisposable,并且再次讓它們在執行 Dispose 時輸出日志。

public?class?OwnedDependency1?:?IOwnedDependency1,?IDisposable{...?Other?code?omitted?for?brevity?...public?void?Dispose(){System.Diagnostics.Debug.WriteLine($"Created?{GetType().Name}?instance?{InstanceNumber}");}}

我們還可以在類的構造函數中添加一些日志記錄。

現在運行應用程序并切換復選框將輸出類似于以下內容的日志文本。

  • Created MyOwningComponent

  • Created OwnedDependency1 instance 1

  • Created OwnedDependency2 instance 1

  • Disposing OwnedDependency2 instance 1

  • Disposing OwnedDependency1 instance 1

  • Disposing MyOwningComponent

  • Created MyOwningComponent

  • Created OwnedDependency1 instance 2

  • Created OwnedDependency2 instance 2

  • Disposing OwnedDependency2 instance 2

  • isposing OwnedDependency1 instance 2

  • Disposing MyOwningComponent

結論

當您的組件只需要擁有一個依賴項時,從 OwningComponentBase<T> 派生;當您的組件需要擁有多個依賴項時,從非泛型 OwningComponentBase 派生。

盡管解析組件依賴項實例的過程是一個手動過程,但不需要處理任何創建的依賴項,因為組件的依賴項容器將在 OwningComponentBase.Dispose 時處理它們。

參考資料

[2]

源代碼: https://github.com/mrpmorris/blazor-university/tree/master/src/DependencyInjection/OwningMultipleDependenciesTheRightWay

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/282817.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/282817.shtml
英文地址,請注明出處:http://en.pswp.cn/news/282817.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Gradle 1.12用戶指南翻譯——第五十四章. 構建原生二進制文件

其他章節的翻譯請參見&#xff1a;http://blog.csdn.net/column/details/gradle-translation.html翻譯項目請關注Github上的地址&#xff1a;https://github.com/msdx/gradledoc本文翻譯所在分支&#xff1a;https://github.com/msdx/gradledoc/tree/1.12。直接瀏覽雙語版的文檔…

android 調用c wcf服務,如何使用命名管道從c調用WCF方法?

更新&#xff1a;通過協議here,我無法弄清楚未知的信封記錄.我在網上找不到任何例子.原版的&#xff1a;我有以下WCF服務static void Main(string[] args){var inst new PlusFiver();using (ServiceHost host new ServiceHost(inst,new Uri[] { new Uri("net.pipe://loc…

VK Cup 2015 - Qualification Round 1 A. Reposts(樹)

傳送門 Description One day Polycarp published a funny picture in a social network making a poll about the color of his handle. Many of his friends started reposting Polycarps joke to their news feed. Some of them reposted the reposts and so on. These event…

Lombok@Builder和@NoArgsConstructor沖突

問題 今天在使用lombok簡化model類時。使用Builder建造者模式。報以下異常 解決辦法。 去掉NoArgsConstructor添加AllArgsConstructor源碼分析 下圖是編譯后的源碼 只使用Builder會自動創建全參構造器。而添加上NoArgsConstructor后就不會自動產生全參構造器

現在商業有種競爭叫“跨界打擊”

隨著互聯網的發展&#xff0c;“跨界打擊”的事情可謂是無處不在。行業跨界打擊會搶占某個行業的市場份額&#xff0c;甚至可能淘汰一個行業。跨界打擊者可能是某個行業的新進入者&#xff0c;也可能是現有競爭者&#xff0c;更可能是徹底的替代者或顛覆者。跨界打擊&#xff0…

架構之美閱讀筆記之一

寒假生活開始了&#xff0c;關于軟件架構這部分的學習&#xff0c;我選擇的是《架構之美》這本書。這本出版于2009年的書&#xff0c;由淺入深地講述了從架構的概述&#xff0c;到企業級應用架構&#xff0c;系統架構&#xff0c;最終用戶應用架構&#xff0c;再到語言與架構模…

ntop linux,Linux下開源監控軟件Ntop的性能提升方案

摘要&#xff1a;Ntop是一款Linux下常見的開源監控軟件&#xff0c;它可以監測的數據包括&#xff1a;網絡流量、使用協議、系統負載、端口情況、數據包發送時間等。正常情況下它工作的時候就像一部被動聲納&#xff0c;默默的接收看來自網絡的各種信息&#xff0c;通過對這些數…

Java異常處理教程

異常是在沒有定義正常執行路徑時在Java程序的執行期間可能出現的條件。Java通過將執行操作的代碼與處理錯誤的代碼分離來處理錯誤。 當發生異常時&#xff0c;Java會創建一個包含有關異常的所有信息的對象&#xff0c;并將其傳遞給相應的異常處理代碼。有關異常的信息包括異常的…

性能優化8--內存泄露

一.根源&#xff1a; 內存泄露簡單說就是已經沒有用的資源&#xff0c;但是由于被其他資源引用著無法被GC銷毀。 二.內存泄露常見場景 1.單例導致內存泄露 單例的靜態特性使得它的生命周期同應用的生命周期一樣長&#xff0c;如果一個對象已經沒有用處了&#xff0c;但是單例還…

那些年,登山徒步記錄,立貼

2018年1月-9月份暫無數據。&#xff08;慘無人道&#xff0c;已經喪失了自我。&#xff09; 10月份2017年2月份02月12日 25.00KM 牛木外線3月份暫無數據。 4月份1.04月09日 16.00KM 火鳳線 5月份1.05月06日 20.00KM 漁帽線&#xff08;第一機耕路&#xff09; 6月份1.06月11日 …

記一次 .NET 某打印服務 非托管內存泄漏

一&#xff1a;背景 1. 講故事前段時間有位朋友在微信上找到我&#xff0c;說他的程序出現了內存泄漏&#xff0c;能不能幫他看一下&#xff0c;這個問題還是比較經典的&#xff0c;加上好久沒上非托管方面的東西了&#xff0c;這篇就和大家分享一下&#xff0c;話不多說&#…

android靜態方法如何測試,android – 如何使用mock()和spy()測試靜態方法

通常情況下,如果你最終使用PowerMock,這是一個很好的跡象,表明你最有可能是錯誤的方式.如果不是直接引用畢加索,而是創建一個組件,它的職責是加載圖像,讓我們說類ImageLoader.這會給你什么&#xff1f;>關注點分離&#xff1a;如果明天你決定轉移到Glide,你不應該改變你使用…

mysql經典的8小時問題-wait_timeout

2019獨角獸企業重金招聘Python工程師標準>>> 前段時間 現網突然頻繁報出 連接不上數據庫&#xff0c;偶滴的妖孽&#xff0c;其他地方都是用mysql&#xff0c;也沒遇到這個問題呀。 java.io.EOFExceptionat at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:1913…

Chrome DevTools — Network

記錄網絡請求 默認情況下&#xff0c;只要DevTools在開啟狀態&#xff0c;DevTools會記錄所有的網絡請求&#xff0c;當然&#xff0c;記錄都是在Network面板展示的。 停止記錄網絡請求 點擊Stop recording network log紅色圖標&#xff0c;當它變為灰色時&#xff0c;表示DevT…

Blazor University 中文版網站已上線

在學習 Blazor 的過程中&#xff0c;找到了一個網站 Blazor University&#xff08;https://blazor-university.com&#xff09;。發現網站內容非常詳實&#xff0c;正像首頁所說的&#xff1a;通過瀏覽本網站中的信息&#xff0c;我打算帶您從完全的新手到Blazor的所有方面的專…

android:paddingtop 百分比,相對層中的百分比寬度

相對層中的百分比寬度我正在為登錄進行表單布局。Activity在我的Android應用程序中。下面的圖片是我希望它看起來的樣子&#xff1a;我能夠通過以下方式實現這個布局XML..問題是&#xff0c;這有點麻煩。我不得不對主機EditText的寬度進行硬編碼。具體而言&#xff0c;我必須具…

MySQL 查看表結構簡單命令

一、簡單描述表結構&#xff0c;字段類型 desc tabl_name; 顯示表結構&#xff0c;字段類型&#xff0c;主鍵&#xff0c;是否為空等屬性&#xff0c;但不顯示外鍵。 例如&#xff1a;desc table_name 二、查詢表中列的注釋信息 select * from information_schema.columns wher…

簡單獲取任意app的URL Schemes

簡單說明 最近業務需要&#xff0c;一直在查詢App的scheme相關信息&#xff0c;找到一種比較可靠的方法&#xff0c;分享給大家 步驟如下&#xff1a; 在電腦上使用iTunes下載那個app下載完后&#xff0c;在itunes里點擊這個app&#xff0c;選擇->Show in Finder&#xff0c…

Java中short、int、long、float、double的取值范圍

一、基本數據類型的特點&#xff0c;位數&#xff0c;最大值和最小值。1、基本類型&#xff1a;short 二進制位數&#xff1a;16 包裝類&#xff1a;java.lang.Short 最小值&#xff1a;Short.MIN_VALUE-32768 &#xff08;-2的15此方&#xff09;最大值&#xff1a;Short.MAX_…

.Net之接口文檔精度丟失處理

目的最近兩天在給朋友講解如何使用ajax調用接口時候&#xff0c;我發現我用swagger調用接口返回的long類型的數據最后幾位都變成了0(例如&#xff1a;6974150586715898000)&#xff0c;本來是以為sqlite數據庫不支持long類型導致我存進去的數據出了問題&#xff0c;然后我使用接…