Blazor (.net 7) 中的三种依赖项注入语法之间有区别吗?

bph*_*bph 2 c# design-patterns dependency-injection blazor

据我所知,所有这三种模式都可以在 Blazor (.net 7/C#/Razor) 项目中注入 DI 服务:

  1. @inject NavigationManager NavManager在 Razor 组件中
  2. [Inject] private NavigationManager NavManager { get; set; }在类定义中
  3. 典型的 DI 模式:
   private readonly IMyDependency _myDependency;
   public Index2Model(IMyDependency myDependency)
   {
       _myDependency = myDependency;            
   }
Run Code Online (Sandbox Code Playgroud)

据我所知,它们都有效。

他们的实现有什么区别吗?使用其中任何一个或全部安全吗?

谢谢!

Dim*_*kos 5

唯一的区别是,您提到的前两种语法应在 Razor 组件中使用,而第三种语法应在所有其他情况下使用。

@inject NavigationManager NavManager语法用于使用标记在 Razor 组件中注入服务。

[Inject] private NavigationManager NavManager { get; set; }用于使用 C# 代码在 Razor 组件中注入服务。(@code { ... }在代码隐藏方法中的内部部分或部分类内部)。

您可以在同一组件中使用这两种方法。

@inject IToDoApi ToDoApi
@inject ISomeServiceType AnotherService

@code
{
  [Inject]
  private IYetAnotherServiceType PropertyInjectedDependency { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

构造函数语法用于将一个服务注入另一个服务。

@inject IToDoApi ToDoApi
@inject ISomeServiceType AnotherService

@code
{
  [Inject]
  private IYetAnotherServiceType PropertyInjectedDependency { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

请求组件中的服务

代码片段来自:将依赖项注入 Blazor 组件


MrC*_*tis 5

迪米特里斯回答的附加信息。

是的,1/2和3之间是有区别的。组件的注入过程(由Renderer进程处理)是在Ctor之后运行的。您不能在 Ctor 中使用任何 DI 服务。

1 和 2 之间的区别在于可空性。

  1. 使用 时@inject,Razor 编译器会禁用对属性的可空检查。
  2. 使用 时[Inject],您需要手动处理。执行此操作的正常方法是将其设置default!为默认值。一旦你到达,它就永远不会为空SetParametersAsync,并且正常的生命周期方法,因为如果运行时找不到服务,它将在注入过程中抛出异常。
[Inject] private NavigationManager NavManager { get; set; } = default!;
Run Code Online (Sandbox Code Playgroud)