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

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

問題來了,為什麼Blazor會知道WeatherForecastService在這裡可以呼叫?

最後更新 2021/12/11 下午1: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 重構,可點擊原文連結與重構後程式碼比較學習,謝謝閱讀,支援原作者

繼續探索

延伸閱讀

更多文章
同分類 / 同標籤 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`)。

繼續閱讀