《ASP.NET Core技术内幕与项目实战》精简集-基础组件1.2:依赖注入
本节内容,涉及P53-P60、P183-P188,NutGet包:Microsoft.Extensions.DependencyInjection
一、.NET中的依赖注入
1 //定义一个接口,作为依赖注入的服务类 2 //ITestService.cs 3 internal interface ITestService 4 { 5 public string Name { get; set; } 6 public void SayHi(); 7 } 8 9 10 11 //定义一个实现接口的类,作为依赖注入的实现类 12 //TestService.cs 13 internal class TestService : ITestService 14 { 15 public string Name { get; set; } 16 17 public void SayHi() 18 { 19 Console.WriteLine($"Hi,我是{Name}"); 20 } 21 } 22 23 24 25 //注册服务和调用服务 26 ServiceCollection services = new ServiceCollection(); 27 28 services.AddTransient<ITestService, TestService>(); 29 30 using (ServiceProvider sp = services.BuildServiceProvider()) 31 { 32 ITestService testService = sp.GetService<ITestService>(); 33 testService.Name = "functionMC"; 34 testService.SayHi(); 35 }
代码解释:
1-21行:面向接口编程,分别定义一个接口及其实现类,注册服务时,接口作为服务类,实现接口的类作为实现类
26行:创建用于注册服务的容器
28行:以瞬态方式注册服务
30行:创建服务定位器
32行:以服务定位器的方式,获取服务
33-34行:调用服务
补充说明:
①依赖注入的本质,是将new对象的事情交给框架,调用服务时,我们声明需要哪个服务,框架会帮我们完成new的事情
②面向接口编程,实现服务类与实现类的解耦。案例中,如果要修改SayHi方法,直接创建另外一个实现接口的类,28行更换一个实现类,30-35行不需要修改代码
③依赖注入具有传染性,如果一个类是通过依赖注入来创建对象,那么这个类就可以注入服务(可以查看P57-P60案例)
④通过依赖注入创建的对象(服务),有三种生命周期:AddTransient-瞬态,每次请求都创建一个新对象;AddScoped-范围,在给定范围内,多次请求共享一个对象,ASP.NET Core的一次Http请求,就是一个范围;AddSingleton-单例,应用共享同一个对象。
二、在ASP.NET Core中使用依赖注入
1 //定义一个接口,作为依赖注入的服务类 2 //ITestService.cs 3 public interface ITestService 4 { 5 public IEnumerable<string> GetNames(); 6 } 7 8 9 //定义一个实现接口的类,作为依赖注入的实现类 10 //TestService.cs 11 public class TestService : ITestService 12 { 13 public IEnumerable<string> GetNames() 14 { 15 return new string[] {"Tom","Jack"}; 16 } 17 } 18 19 20 21 //注册服务,在MiniApi中注入服务并调用 22 var builder = WebApplication.CreateBuilder(args); 23 builder.Services.AddScoped<ITestService,TestService>(); 24 25 var app = builder.Build(); 26 27 app.MapGet("/", (ITestService testService) => 28 { 29 var names = testService.GetNames(); 30 return string.Join(",",names); 31 }); 32 33 app.Run();
代码解释:
22-23行:WebApplication.CreateBuild方法,返回WebApplicationBuilder对象,此对象的Services属性,就是我们需要的容器,不需要手动创建,直接注册服务
27-31行:MiniApi中,通过参数注入服务,并调用ITestService对象的GetName方法。如果在控制器中使用,可以通过构造函数注入
补充说明:
①获取服务的方式有:构造函数注入,方法参数注入和服务定位器。控制器中,一般使用构造函数注入,MiniApi中我们使用后两种方式
②在控制器中,如果此对象只有某个方法使用,也建议使用参数注入,NET6控制器方法的参数注入需要使用如下格式:([FromServices]ITestService testService)。NET7可以不使用[FromServices]标注
特别说明:
1、本系列内容主要基于杨中科老师的书籍《ASP.NET Core技术内幕与项目实战》及配套的B站视频视频教程,同时会增加极少部分的小知识点
2、本系列教程主要目的是提炼知识点,追求快准狠,以求快速复习,如果说书籍学习的效率是视频的2倍,那么“简读系列”应该做到再快3-5倍