The question arises, why does Blazor know that WeatherForecastService can be called here?
Click Program.cs and you can find a line of code:
builder.Services.AddSingleton<WeatherForecastService>();
把这段代码注释,重新加载网页,点击Fetch data菜单,可以在页面看到下面的异常警告信息(只在页脚显示了一个警告块),详细警告看终端输出,因为我们试图在 FetchData.razor 调用 WeatherForecastService,却没告诉 Blazor 我们要注册这个服务。


Copy the prompt and take a look. This prompt is very clear:
Cannot provide a value for property 'ForecastService' on type 'BlazorServer.Pages.FetchData'. There is no registered service of type 'BlazorServer.Data.WeatherForecastService'.
However, this is not the dependency injection mentioned by Day03. The purpose of dependency injection is to get rid of the dilemma that high-level programs must rely on lower-level programs to reduce coupling. For example, if FetchData.razor wants to call other services today, such as the NewWeatherForecastService method with the same name, GetForecastAsync, to retrieve 10 pieces of data, then everything that uses WeatherForecastService must be modified. At present, because there is not much to do with the Demo, I don't feel it. What if there are 10 to 20 things that need to be changed in the future?
这时候就是依赖注入发挥功能的时候了,先定义一个接口: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 use IWeatherForecastService to register with NewWeatherForecastService

Look at the screenshot above. In FetchData.razor, IWeatherForecastService is also injected instead
After reloading and loading the web page, you can see that the number of data items has become 10

The core of dependency injection is that "the dependence on a certain function is through injection." It does not directly call the underlying program, but calls the interface of the underlying program. Even if the underlying program is modified, it will not cause all callers calling the program to change.
** Note: Since I only remembered the life cycle after writing this article, I originally wanted to use the git rebase function to go back to this commit and add a Demo, but I would have doubts about git decapitation, so I will explain the life cycle again on Day 07. Please forgive me for any inconvenience. **
** Note: The code in this article is refactored through. NET 6 + Visual Studio 2022. You can click on the original link to compare and learn the refactored code. Thank you for reading and support the original author **