学习AddSingleton、AddScoped、AddTransient三个方法区别
AddSingleton()方法创建一个Singleton服务,首次请求会创建服务,然后,所有后续的请求中都会使用相同的实例,整个应用程序生命周期都使用该单个实例
AddScoped():不同http清求,实例不同,同名谓词不同,也不行。例如httpget跟httppost,作用域是一定范围内,例如从同一个post请求的create方法,只能统计一次,每次请求都是新的实例
AddTransient():临时服务,每次请求时,都会创建一个新的Transient服务实例
使用例子:
Startup.cs里:
public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<IStudentRepository, MokeStudentRepository>();//services.方法
}
AddSingleton的生命周期:
项目启动-项目关闭 相当于静态类 只会有一个
AddScoped的生命周期:
请求开始-请求结束 在这次请求中获取的对象都是同一个
AddTransient的生命周期:
请求获取-(GC回收-主动释放) 每一次获取的对象都不是同一个
从功能上看,AddSingleton()、AddTransient()、AddScoped() 都是依赖注入(DI) 的方式向系统中注入对象或服务。这就是我们疑惑的地方,因为三个方法的功能几乎一样。
但是它们的生命周期(作用范围、作用时间、作用域)是不一样的:
AddSingleton() 的生命周期为 项目启动 -> 项目结束,即存在于整个应用的生命周期内,相当于全局单例模式。
AddScoped() 的生命周期为 Http 请求开始 -> Http 响应结束,即存在于每一个 HTTP 请求周期内。
AddTransient() 的生命周期为 请求服务对象开始 -> (GC 主动回收-主动释放),即仅限于程序作用域。
因为生命周期的不一样,如果一个作用域范围内同时存在以上三种方式注入的服务或对象,那么在使用时,权重就是下面这样
AddSingleton < AddTransient < AddScoped
也就是
AddSingleton() 创建的对象可以在 AddTransient() 和 AddScoped() 对象中使用。
AddTransient() 创建的对象基本可以在 AddScoped() 对象中使用,但有时候也不行。
AddScoped() 创建的对象几乎不能在 AddTransient() 对象中使用,但并不绝对。
为什么是这样的呢?
这是因为 AddScoped() 对象是在接受一个 Http 请求时创建的,所以不能在 AddSingleton() 对象中使用,甚至也不能在 AddTransient() 对象中使用。