Blazor University (52)依赖注入 —— 拥有多个依赖项:正确的方式
Posted dotNET跨平台
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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;
当 ShowComponent
为 true
时,我们的标记将创建 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);
然后,对于我们的每个依赖类(OwnedDependency1
和 OwnedDependency2
),让它们实现 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
以上是关于Blazor University (52)依赖注入 —— 拥有多个依赖项:正确的方式的主要内容,如果未能解决你的问题,请参考以下文章
Blazor University (48)依赖注入 —— Scoped 依赖
Blazor University (49)依赖注入 —— 比较依赖范围
Blazor University (46)依赖注入 —— Transient 依赖