Blazor University (45)依赖注入 —— 将依赖项注入 Blazor 组件

原文链接:https://blazor-university.com/dependency-injection/injecting-dependencies-into-blazor-components/

将依赖项注入 Blazor 组件

源代码[1]

定义我们的依赖

在注入依赖之前,我们需要创建一个。我们将使用古老的 ToDo 示例,但请放心,我们不会创建 ToDo 应用程序。

首先创建一个基本的 ToDo 类。

public class ToDo
{public int Id { get; set; }public string Title { get; set; }public bool Completed { get; set; }
}

接下来,我们将创建 Blazor 页面或组件可能需要的类。在这种情况下,它将是一个从服务中检索 ToDo 条目的 API。我们实际上不会调用服务器,我们只会返回一些模拟数据。

using System.Collections.Generic;
using System.Threading.Tasks;namespace BasicDependencyInjection
{public interface IToDoApi{Task<IEnumerable<ToDo>> GetToDosAsync();}public class ToDoApi : IToDoApi{private readonly IEnumerable<ToDo> Data;public ToDoApi(){Data = new ToDo[]{new ToDo { Id = 1, Title = "To do 1", Completed = true},new ToDo { Id = 2, Title = "To do 2", Completed = false},new ToDo { Id = 3, Title = "To do 3", Completed = false},};}public Task<IEnumerable<ToDo>> GetToDosAsync() => Task.FromResult(Data);}
}

我们通过实现接口抽象了服务。如果我们希望在对我们的类进行单元测试时通过模拟,这是一个很好的做法。

注册可注入依赖项

当 Blazor 应用程序运行其启动代码时,它为我们做的一件事就是配置一个依赖注入容器。依赖注入容器负责构建类的实例(及其依赖项的实例等)。

在这个引导过程中,我们需要注册我们希望将哪些类作为自动注入依赖项可用。我们可以将一个类本身注册为可注入的,如下所示:

services.AddSingleton<ToDoApi>();

或者我们可以将接口注册为可注入的,只要我们另外指定实现该接口的类即可。

service.AddSingeton<IToDoApi, ToDoApi>();

注意: 同样,为了使单元测试更简单,推荐使用后一种方法。它还允许在配置文件中指定实现类——例如,我们可以根据部署的平台是开发/测试/生产来指定不同的 IEmailService。

其他注册依赖的模式是:

// Register an existing object instance
services.AddSingleton(existingObject);// Register an existing object instance, injected via an interface
services.AddSingleton<ISomeInterface>(implementingInstance);// Lazy created instance, with manual build process and access to the current IServiceProvider
services.AddSingleton<ISomeInterface>(serviceProvider => new ImplementingType(.......));

Blazor Server 和 Blazor WASM 应用程序中的引导代码并不相同,因此,尽管服务注册相同,但我们必须去注册可注入依赖项的位置略有不同。

在 Blazor Server 应用程序中注册注入

在 Blazor Server 应用中,有一个带有 ConfigureServices 方法的 Startup 类。这是我们应该执行注册的地方。

public void ConfigureServices(IServiceCollection services)
{... default Blazor registrations omitted ...// Register our own injectablesservices.AddSingleton<IToDoApi, ToDoApi>();
}

当我们在创建应用程序时选中 ASP.NET Core 托管复选框时,WASM 应用程序也是如此。这是因为服务器负责引导整个应用程序。

62ad9d22a7793a9e3aa5e1a6fe8b4d64.jpeg

在 Blazor WASM 应用程序中注册注入

当我们的 Blazor 项目是独立的 WASM 应用程序(不是 ASP.NET Core 托管)时,该应用程序必须有自己的引导程序类。在这种类型的应用程序中,类名为 Program,引导方法名为 Main——就像在控制台应用程序中一样。

public static async Task Main(string[] args)
{var builder = WebAssemblyHostBuilder.CreateDefault(args);builder.RootComponents.Add<App>("app");builder.Services.AddTransient(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });// Register our own injectablesbuilder.Services.AddSingleton<IToDoApi, ToDoApi>();await builder.Build().RunAsync();
}

注入依赖

对于非 Blazor 类,例如其他可注入服务,可以通过类的构造函数注入依赖项。

public class NewsletterService : INewsletterService
{private readonly IEmailService EmailService;public NewsletterService(IEmailService emailService){EmailService = emailService;}
}

但是,Blazor 组件并非如此。目前不支持构造函数注入。有两种方法可以指示我们的组件使用哪些依赖项;一个在 Razor 标记中,一个在 C# 代码中。

@inject IToDoApi ToDoApi
@inject ISomeServiceType AnotherService@code
{[Inject]private IYetAnotherServiceType PropertyInjectedDependency { get; set; }
}

InjectAttribute 只能应用于具有属性设置器的属性,属性的封装级别无关紧要。

注意: 这两种方法是相同的。事实上,@inject 语法只是 [Inject] 语法的简写。在构建我们的应用程序时,Blazor 将首先将 Razor 标记转换为 C# 源代码。要查看 @inject 语法是如何转换的,请打开文件夹 **\obj\Debug\netcoreapp3.1\Razor ** 并查找与 razor 文件对应的 .cs 文件。

使用注入的依赖项

在创建 Blazor 组件实例之后和执行 OnInitializedOnInitializedAsync 生命周期事件之前注入依赖项。这意味着我们不能覆盖组件的构造函数并从那里使用这些依赖项,但我们可以在 OnInitialized* 方法中使用它们。

要使用我们的 IToDoApi 服务,我们只需使用 @inject 语法将其注入 Index 页面,然后在页面初始化时调用它。

@page "/"
@inject IToDoApi ToDoApi<h1>To do</h1>
@if (Data.Any())
{<table class="table"><thead><tr><th>Id</th><th>Title</th><th>Completed</th></tr></thead><tbody>@foreach (ToDo item in Data){<tr><td>@item.Id</td><td>@item.Title</td><td>@item.Completed</td></tr>}</tbody></table>
}@code
{private IEnumerable<ToDo> Data = Array.Empty<ToDo>();protected override async Task OnInitializedAsync(){await base.OnInitializedAsync();Data = await ToDoApi.GetToDosAsync();}
}
  • 第 2 行

    IToDoApp 的实例被注入到我们的页面中,我们使用名称 ToDoApi 来引用注入的依赖项。

  • 第 35 行

    在注入的服务上调用 GetDoToAsync 方法。等待该方法并将结果存储在 Data 中。

  • 第 16-23 行

    Data 中的项目使用 @foreach 循环进行迭代,并将输出呈现为我们视图的一部分。

  • eb8c576791a97ebf11c6f6032da84500.png

参考资料

[1]

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/283556.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

顾小清:人工智能何以促进未来教育发展

自工业革命以来&#xff0c;人类社会的发展总是在技术与教育的角逐互动中前行。技术作为推动人类历史发展的核心推进力&#xff0c;与教育这一“人力资本发动机”竞相成为推动经济社会发展的主力。人工智能作为第四次工业革命的显著标签&#xff0c;其飞速发展正在逐步塑造社会…

server 2008R2 AD域环境中DHCP服务器的授权步骤

百度了下&#xff0c;没有详细的授权步骤&#xff0c;找了好久才找到&#xff0c;拿出来分享下环境&#xff1a;dhcp服务器在ad服务器中登陆dhcp服务器&#xff0c;管理工具-dhcp&#xff0c;打开dhcp&#xff0c;点击操作&#xff0c;管理授权&#xff08;终于找到了&#xff…

基于scikit-learn机器学习库的分类预测

一旦你在scikit-learn中选择好机器学习模型&#xff0c;就可以用它来预测新的数据实例。初学者经常会有这样的疑问&#xff1a; 如何在scikit-learn中用我自己的模型进行预测&#xff1f; 在本教程中&#xff0c;你将会发现如何在Python的机器学习库scikit-learn 中使用机器学习…

.NET性能优化-快速遍历List集合

简介System.Collections.Generic.List<T>是.NET中的泛型集合类&#xff0c;可以存储任何类型的数据&#xff0c;因为它的便利和丰富的API&#xff0c;在我们平时会广泛的使用到它&#xff0c;可以说是使用最多的集合类。在代码编写中&#xff0c;我们经常需要遍历一个Lis…

Thread、Runnable、Callable、Future ... 的关系?

Thread、Runnable、Callable、Future、FutureTask&#xff0c;你能详细讲出他们的内部关系么&#xff1f;这也是面试经常问到的问题。 1. Thread 和 Runnable 1.1 Thread 我们先看一下 Thread 最简单的使用姿势&#xff1a; public class MyThread extends Thread {public M…

EntityFramework6.X 之 Fulent

Fulent Fulent是配置领域模型类的另一个方法&#xff0c;它比DataAnnotations提供更多的配置&#xff0c;提供以下三种方法映射 Mappings To Database Model-Wide Mapping 设置默认架构&#xff0c;设置经典约束 Entity Mapping 映射单个或多个表格或架构&#xff0c;映射…

Visual Studio 2022 正式支持 .NET MAUI 开发

点击上方蓝字关注我们&#xff08;本文阅读时间&#xff1a;5分钟)我们很高兴地宣布 Visual Studio 2022 正式支持 .NET MAUI 开发。现在&#xff0c;您可以使用 .NET 更快地构建跨平台原生客户端应用程序&#xff0c;并将它们从单个代码库发布到 Android、iOS、macOS 和 Windo…

python访问数据库

1. python DB api简介 python DB api python访问数据库的统一接口规范&#xff0c;详细可参考https://www.python.org/dev/peps/pep-0249/python DB api中主要包括三个重要的对象 数据库连接对象 connection&#xff0c;数据库交互对象 cursor和数据库异常类 exceptions2. 使用…

错误:“filesystem“ 不是 “std“ 的成员

分析原因&#xff1a;应该项目是C版本问题 1、项目属性 → 配置属性 → 常规 → C语言标准 2、项目属性 → C/C → 语言 → C语言标准 3、项目属性 → C/C → 建议行 → 其它选项 → 添加&#xff1a;/Zc:__cplusplus

Blazor预研与实战

背景最近一直在搞一件事&#xff0c;就是熟悉Blazor&#xff0c;后期需要将Blazor真正运用到项目内。前期做了一些调研&#xff0c;包括但不限于Blazor知识学习组件库生态预研与现有SPA框架做比对与WebForm做比对自己动手做个演示项目最终的体验非常不错&#xff0c;功能全面。…

并发编程10大坑,你踩过几个?

目录 前言 1. SimpleDateFormat线程不安全 2. 双重检查锁的漏洞 3. volatile的原子性 4. 死锁 4.1 缩小锁的范围 4.2 保证锁的顺序 5. 没释放锁 6. HashMap导致内存溢出 7. 使用默认线程池 8. Async注解的陷阱 9. 自旋锁浪费cpu资源 10. ThreadLocal用完没清空 前…

CAP理论与MongoDB一致性、可用性的一些思考

大约在五六年前&#xff0c;第一次接触到了当时已经是hot topic的NoSql。不过那个时候学的用的都是mysql&#xff0c;Nosql对于我而言还是新事物&#xff0c;并没有真正使用&#xff0c;只是不明觉厉。但是印象深刻的是这么一张图片&#xff08;后来google到图片来自这里&#…

【开源】一个WPF开发的XML记事本

今天推荐一个WPF开源项目&#xff1a;XmlNotepad[1]。此仓库由 WPF开发者[2] 推荐&#xff0c;站长简单翻译分享。介绍XML Notepad[3] 是一个 Windows 程序&#xff0c;它为浏览和编辑 XML 文档提供了一个简单直观的用户界面。有四种安装方式&#xff1a;ClickOnce 安装程序[4]…

log4j2 mybatis 显示 sql 和 结果集

为什么80%的码农都做不了架构师&#xff1f;>>> 首先说明版本&#xff1a; log4j 版本是 第2版beta9&#xff0c;引用jar包 log4j-api-2.0-beta9.jar log4j-core-2.0-beta9.jar mybatis 是 mybatis-3.2.3 log4j2 配置 如下&#xff0c;命名为 log4j2.xml&#xff0…

深入解析volatile关键字

目录 1. 初步认识volatile 2. volatile的特性一&#xff1a;保证可见性 2.1 volatile关键字是如何保证可见性的&#xff1f; 2.2 从JMM来看可见性 2.3 从硬件层面了解可见性的本质 2.3.1 CPU高速缓存 2.3.2 缓存一致性 2.3.3 MESI 协议 2.3.4 缓存一致性小结 3. vola…

Nginx基础配置

一、主配置文件结构main block&#xff1b;#全局块配置全局生效event{#事件驱动相关配置 }http{#http/https协议相关配置段 server { ... }&#xff1a;#每个server用于定义一个虚拟主机&#xff1b; server { ... server_name root alias location [OPERATOR] URL { ... if CO…

上周面试回来后写的Java面试总结,想进BAT必看

上周陪同之前一起工作的同事去面试&#xff08;乔治&#xff0c;小袁&#xff0c;鹏飞&#xff08;面试人&#xff09;&#xff09;&#xff0c;第一站是去深圳&#xff0c;第二站上海&#xff0c;第三站杭州。面试什么公司我在这里就不多说了&#xff0c;你们知道是一线公司就…

从贝叶斯方法谈到贝叶斯网络

从贝叶斯方法谈到贝叶斯网络0 引言其实。介绍贝叶斯定理、贝叶斯方法、贝叶斯判断的资料、书籍不少&#xff0c;比方《数理统计学简史》&#xff0c;以及《统计决策论及贝叶斯分析 James O.Berger著》等等&#xff0c;然介绍贝叶斯网络的中文资料则非常少。中文书籍总共也没几本…

k8s 读书笔记 - kubectl 命令行工具用法详解

kubectl 在 k8s 集群中作为 客户端 CLI 工具&#xff0c;可以让用户使用 kubectl 工具执行命令行&#xff0c;并通过使用 k8s API 与 k8s 集群的控制面&#xff08;kube-controller-manager&#xff09;进行通信。kubectl 语法格式kubectl 命令行的语法格式如下&#xff1a;kub…

初级必备:单例模式的7个问题

故事 实话实说&#xff0c;关于单例模式&#xff0c;网上有N多个版本。你估计也看过很多版本。但看完了又能怎样&#xff1f;我技术群里的一位小伙伴&#xff0c;上周面试&#xff0c;就因为一个单例模式&#xff0c;然后叫他回去等通知了。 下面是这位同学被问到的问题&…