2.2.1 核心模块--依赖注入
- 什么是依赖注入
- .NET Core DI 生命周期
- 服务设计
- 服务范围检查
ASP.NET Core 依赖注入:https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-5.0
什么是依赖注入
Dependency injection 依赖注入
Inversion of Control 控制反转
依赖注入 与 依赖查找
依赖注入:通过编排告诉 IOC 容器整个内部类之间的依赖关系
依赖查找:通过回调或者上下文获取依赖
asp .net core 如何实现
在上一小节新建的 HelloApi 项目中修改 Program.cs
namespace HelloApi
{
public class Program
{
public static void Main(string[] args)
{
var host = CreateHostBuilder(args).Build();
Console.WriteLine("Server started");
// 依赖查找
var helloService = host.Services.GetRequiredService<IHelloService>();
helloService.Hello();
host.Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureServices((ctx,services)=>
{
// 依赖注入
// 任何时候获取到的都是一个新的实例
services.AddTransient<IHelloService, HelloService>();
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
}
IHelloService
namespace HelloApi.Services
{
public interface IHelloService
{
void Hello();
}
}
HelloService
namespace HelloApi.Services
{
public class HelloService : IHelloService
{
public void Hello()
{
Console.WriteLine("hello dotnet core");
}
}
}
.NET Core DI 生命周期
// 依赖注入
// 任何时候获取到的都是一个新的实例
services.AddTransient<IHelloService, HelloService>();
// 每个 scope 都有一个实例
services.AddScoped<IHelloService, HelloService>();
// 单例,整个应用程序的生命周期只有一个实例
services.AddSingleton<IHelloService, HelloService>();
通过 id 区分不同的服务生命周期
HelloService
private string _id;
public HelloService()
{
_id = Guid.NewGuid().ToString();
}
Program.cs
// 依赖查找
var helloService1 = host.Services.GetRequiredService<IHelloService>();
helloService1.Hello();
var helloService2 = host.Services.GetRequiredService<IHelloService>();
helloService2.Hello();
启动程序,输出如下:
Server started
hello dotnet core: cc77ee85-3806-4c29-b693-8da8bcf40498
hello dotnet core: 3306bebc-2340-4645-82e7-0e15fac0e9c7
AddSingleton
Program.cs
.ConfigureServices((ctx,services)=>
{
// 依赖注入
// 单例,整个应用程序的生命周期只有一个实例
services.AddSingleton<IHelloService, HelloService>();
})
启动程序,输出如下:
Server started
hello dotnet core: 35aa7646-e2bd-4d44-8f15-cd6aca3b0215
hello dotnet core: 35aa7646-e2bd-4d44-8f15-cd6aca3b0215
AddScoped
需要自定义一个 scope
Program.cs
using (var scope = host.Services.CreateScope())
{
// 依赖查找
var helloService1 = scope.ServiceProvider.GetRequiredService<IHelloService>();
helloService1.Hello();
var helloService2 = scope.ServiceProvider.GetRequiredService<IHelloService>();
helloService2.Hello();
}
.ConfigureServices((ctx,services)=>
{
// 依赖注入
// 每个 scope 都有一个实例
services.AddScoped<IHelloService, HelloService>();
})
启动程序,输出如下:
Server started
hello dotnet core: abf083e2-7914-43b9-8e7f-540381a05b37
hello dotnet core: abf083e2-7914-43b9-8e7f-540381a05b37
服务设计
- 不要使用静态类和静态成员,不要使用全局状态,而改为使用全局单例类
- 不要在内部自己实例化对象
- 每一个服务应该尽可能地小、易创建、易测试
服务范围检查
singleton 的服务不能依赖于 scoped 的服务
GitHub源码链接:
https://github.com/MINGSON666/Personal-Learning-Library/tree/main/ArchitectTrainingCamp/HelloApi