(5/30)大家一起学Blazor:依赖注入(Dependency Injection)

(5/30)大家一起学Blazor:依赖注入(Dependency Injection)

问题来了,为什么Blazor会知道WeatherForecastService在这里可以调用?

最后更新 2021-12-11 13:27
StrayaWorker
预计阅读 3 分钟
分类
Blazor
专题
一起学Blazor系列
标签
.NET C# ASP.NET Core Blazor

问题来了,为什么 Blazor 会知道 WeatherForecastService 在这里可以调用?

点开 Program.cs,可以找到一行代码:

builder.Services.AddSingleton<WeatherForecastService>();

把这段代码注释,重新加载网页,点击Fetch data菜单,可以在页面看到下面的异常警告信息(只在页脚显示了一个警告块),详细警告看终端输出,因为我们试图在 FetchData.razor 调用 WeatherForecastService,却没告诉 Blazor 我们要注册这个服务。

页面异常警告提示

终端异常打印

复制提示看看,这个提示很明确:

Cannot provide a value for property 'ForecastService' on type 'BlazorServer.Pages.FetchData'. There is no registered service of type 'BlazorServer.Data.WeatherForecastService'.

不过这并不是 day03 说到的依赖注入,依赖注入的目的是摆脱高层级程序必须依赖于低层级程序的窘境,以减少耦合性。举例来说,如果今天 FetchData.razor 要调用其他 Service,例如 NewWeatherForecastService 的同名方法 GetForecastAsync,取回 10 条数据,那只要用到 WeatherForecastService 的地方都必须修改,目前因为 Demo 的关系不多所以没感觉,如果日后有 10 几 20 几个地方要改呢?

这时候就是依赖注入发挥功能的时候了,先定义一个接口:interface IWeatherForecastService

namespace BlazorServer.Data;

public interface IWeatherForecastService
{
	Task<WeatherForecast[]> GetForecastAsync(DateTime startDate);
}

里面就写我们要的方法:Task<WeatherForecast[]> GetForecastAsync(DateTime startDate);

也不用实现(虽然接口也能实现:站长注:在C#8.0中,针对接口引入了一项新特性,就是可以指定默认实现,方便对已有实现进行扩展,也对面向Android和Swift的Api进行互操作提供了可能性。),接着让 WeatherForecastService 跟 NewWeatherForecastService 继承 IWeatherForecastService

服务实现接口

Program.cs 改用 IWeatherForecastService 跟 NewWeatherForecastService 注册

接口注入服务

看上面截图,在 FetchData.razor 中,也改为注入 IWeatherForecastService

重整加载网页就能看到数据条数变为 10 条了

10条数据展示

依赖注入的核心就是「对某个功能的依赖性是通过注入的方式」,不直接调用底层程序,而是调用底层程序的接口,即便底层程序修改也不会导致所有调用该程序的调用端都必须改动。

注:由于笔者是在写完这篇之后才想起来生命周期,原本想用 git rebase 的功能回到这一次的 commit 新增 Demo,但会有 git 断头疑虑,所以笔者会在 day 07 再说明生命周期,若有不便敬请见谅。

注:本文代码通过 .NET 6 + Visual Studio 2022 重构,可点击原文链接与重构后代码比较学习,谢谢阅读,支持原作者

Keep Exploring

延伸阅读

更多文章
同分类 / 同专题 2021-12-25

(29/30)大家一起学Blazor:Blazor单元测试

开发一个系统最无聊的过程大概就是解决BUG了,尤其是那种尝试对null 对象取值的错误(`Object reference not set to an instance of an object.`),这应该是大部分人刚踏入编程领域最常碰到的问题,为了从枯燥的解决BUG过程解脱,这篇就来介绍`单元测试`。

继续阅读
同分类 / 同专题 2021-12-25

(28/30)大家一起学Blazor:Policy-based authorization

之前有说到`ASP.NET Core Identity` 使用的是基于`Claim` 的验证,其实`ASP.NET Core Identity` 有不同类型的授权方式,最简单的`登录授权`、`角色授权`、`Claim 授权`,但上述几种都是以一种方式实现:原则授权(`Policy-based authorization`)。

继续阅读