原文鏈接:https://blazor-university.com/dependency-injection/component-scoped-dependencies/owning-multiple-dependencies-the-wrong-way/
擁有多個依賴項:錯誤的方式
`OwningComponentBase`[1] 類是一個合適的解決方案,當我們需要我們的組件只擁有一個獨立的依賴實例(以及它所依賴的任何 Scoped/Transient 依賴)時。但是,有時我們需要我們的組件擁有多個依賴項。
本節將演示實現此目標的錯誤方法,然后下一節將演示如何正確實現它。
概述
源代碼[2]
使用 OwningComponentBase<T>
時要記住的是,只有在組件擁有的注入容器中創建的 T
(存儲在名為 Service
的屬性中)。
在 OwningComponentBase<T>
的派生類上使用 @inject
指令將不會從組件自己的注入容器中注入依賴項。
注意: 如果您還沒有這樣做,如果您還不熟悉此類如何創建自己的注入容器,請閱讀有關 OwningComponentBase[3] 的部分。
示例
對于本練習,我們將創建一個新的 Blazor 應用程序,該應用程序將演示通過 OwningComponentBase<T>
中的 T
和 @inject
指令為我們的組件提供的服務的不同生命周期。
首先,創建一個新項目,并添加以下服務。
public?interface?IOwnedDependency
{public?int?InstanceNumber?{?get;?}
}public?class?OwnedDependency?:?IDependencyOne
{private?static?volatile?int?PreviousInstanceNumber;public?int?InstanceNumber?{?get;?}public?OwnedDependency(){InstanceNumber?=System.Threading.Interlocked.Increment(ref?PreviousInstanceNumber);}
}
該類只是根據增加一個靜態字段為自己分配一個新的 InstanceNumber
,為每個實例提供一個序號。
接下來,使用名稱 InjectedDependency
創建一段相同的代碼并注冊服務。
//?Server-side?apps,?edit?Startup.cs
services.AddScoped<IOwnedDependency,?OwnedDependency>();
services.AddScoped<IInjectedDependency,?InjectedDependency>();//?WebAssembly?apps,?edit?Program.cs
builder.Services.AddScoped<IOwnedDependency,?OwnedDependency>();
builder.Services.AddScoped<IInjectedDependency,?InjectedDependency>();
使用依賴
現在在 /Shared 文件夾中創建一個名為 MyOwningComponent 的組件,如下所示:
@inherits?OwningComponentBase<IOwnedDependency>
@inject?IInjectedDependency?InjectedDependency<div>Service.InstanceNumber?=?@Service.InstanceNumber
</div>
<div>InjectedDependency.InstanceNumber?=?@InjectedDependency.InstanceNumber
</div>
第 1 行
從
OwningComponentBase<IOwnedDependency>
繼承我們的組件,因此我們的組件將創建自己的注入容器并從中解析IOwnedComponent
的實例。第 2 行
使用標準
@inject
指令讓 Blazor 將IInjectedDependency
的實例注入我們的組件。
顯示結果
最后,我們將編輯 Index.razor 文件。我們將創建一個布爾字段,并且僅在該字段為 true
時才渲染 MyOwnedComponent
。這將告訴 Blazor 在需要時創建組件的實例,并在不需要時釋放它。我們將 @bind
一個 HTML 復選框以允許用戶切換組件。
@page?"/"<input?id="show-component"?type=checkbox?@bind=ShowComponent/>
<label?for="show-component">Show?component</label>@if?(ShowComponent)
{<MyOwningComponent/>
}@code
{bool?ShowComponent?=?false;
}
運行應用程序并切換復選框的狀態將顯示以下內容。
步驟 | 擁有的服務 | 注入的服務 |
---|---|---|
1 | 實例編號 = 1 | 實例編號 = 1 |
2 | 實例編號 = 2 | 實例編號 = 1 |
3 | 實例編號 = 3 | 實例編號 = 1 |
結論
使用 @inject
指令時,Blazor 將從與當前用戶會話(當前瀏覽器選項卡)關聯的依賴項容器中注入 Scoped
依賴項。只有 OwnedComponentBase<T>
中的 T
會從與我們的 OwningComponentBase<T>
派生組件的實例一起創建和銷毀的注入容器中解析。
組件擁有多個依賴項的正確方法將在有關非泛型 OwningComponentBase[4] 類的部分中介紹。
參考資料
[2]
源代碼: https://github.com/mrpmorris/blazor-university/tree/master/src/DependencyInjection/OwningMultipleDependenciesTheWrongWay