AddTransient瞬时模式:每次请求,都获取一个新的实例。即使同一个请求获取多次也会是不同的实例
(注意这里的获取多次对象是指通过上下文获取对象,而不是共用上一个对象)
AddScoped:每次请求,都获取一个新的实例。同一个请求获取多次会得到相同的实例
AddSingleton单例模式:每次都获取同一个实例
Transient:踹神特
Scoped:死靠扑
下面解释下这三种的区别。
/* * 演示依赖注入生命周期的例子 */ [Route("api/[controller]")] [ApiController] public class DIDemoController : ControllerBase { private readonly IBlogNewsService _blogNewsService; public DIDemoController(IBlogNewsService blogNewsService) { _blogNewsService = blogNewsService; } /// <summary> /// 实例对象在一个方法中多次调用的情况 /// </summary> /// <returns></returns> [HttpGet("GetBlogNews2")] public async Task<IActionResult> GetBlogNews2() { var data = await _blogNewsService.QueryAsync(); //执行第二遍 var data2 = await _blogNewsService.QueryAsync(); //测试结论:无论是哪种注入方式,在同一个http请求中,_blogNewsService都是同一个对象,因为这就是同一个对象_blogNewsService啊,哈哈 //只有AddSingleton注入时,_blogNewsService只会实例在系统中实例化一次,其他之后的http请求都不会实例了,因为是单例 //AddTransient注入时和AddScoped注入时,每次http请求都会重新实例化 _blogNewsService!!!! return new JsonResult(new { first = "第一个实例:" + _blogNewsService.GetHashCode(), seconed = "第二个实例:" + _blogNewsService.GetHashCode(), }); } /// <summary> /// 在同一个方法中获取多次实例对象的情况 /// </summary> /// <returns></returns> [HttpGet("GetBlogNews3")] public async Task<IActionResult> GetBlogNews3() { //实例_blogNewsService var data = await _blogNewsService.QueryAsync(); //重新获取一个实例new_blogNewsService IBlogNewsService new_blogNewsService = HttpContext.RequestServices.GetService(typeof(IBlogNewsService)) as IBlogNewsService; var data2 = await new_blogNewsService.QueryAsync(); //测试结论:AddTransient注入时,同一个http请求时,_blogNewsService和new_blogNewsService不是同一个对象。不同http请求时,_blogNewsService和new_blogNewsService不是同一个对象。 //AddScoped注入时,同一个http请求时,_blogNewsService和new_blogNewsService是同一个对象。不同的http请求,_blogNewsService和new_blogNewsService也是同一个对象,只不过跟另一个http请求不是一个实例 //AddSingleton注入时,_blogNewsService和new_blogNewsService是同一个对象,无论他是哪个http接口,整个系统中就这一个实例。 return new JsonResult(new { first = "第一个实例:" + _blogNewsService.GetHashCode(), seconed = "第二个实例:" + new_blogNewsService.GetHashCode(), }); } }
//以下测试依赖注入的生命周期 /* services.AddScoped<IBlogNewsRepository, BlogNewsRepository>(); services.AddScoped<IBlogNewsService, BlogNewsService>(); //*/ services.AddTransient<IBlogNewsRepository, BlogNewsRepository>(); services.AddTransient<IBlogNewsService, BlogNewsService>(); //*/ /* services.AddSingleton<IBlogNewsRepository, BlogNewsRepository>(); services.AddSingleton<IBlogNewsService, BlogNewsService>(); //*/
测试结果:
1、AddSingleton不用多说了,整个系统单例模式,都是同一个实例对象。
2、AddScoped注入方式
(1)首先第一次访问GetBlogNews2
{ "first": "第一个实例:35835861", "seconed": "第二个实例:35835861" }
(2)再一次访问GetBlogNews2
{ "first": "第一个实例:10479095", "seconed": "第二个实例:10479095" }
得出结论:同一个请求,通过AddScoped注入的对象,在多次使用该对象时,都是同一个实例。(其实好理解,这就是同一个对象_blogNewsService,只不过多次调用罢了)
不同的请求,通过AddScoped注入的对象,在多次使用该对象时,都是同一个实例。只不过不同的http请求,两个对象的实例是不一个。
(3)首先第一次访问GetBlogNews3
{ "first": "第一个实例:66980443", "seconed": "第二个实例:66980443" }
(4)再一次访问GetBlogNews3
{ "first": "第一个实例:53734993", "seconed": "第二个实例:53734993" }
得出结论:同一个请求,通过AddScoped注入的对象,在多次使用该对象时,都是同一个实例。
不同的请求,通过AddScoped注入的对象,在多次使用该对象时,都是同一个实例。只不过不同的http请求,两个对象的实例是不一个。
3、AddTransient注入方式
(1)首先第一次访问GetBlogNews2
{ "first": "第一个实例:6451435", "seconed": "第二个实例:6451435" }
(2)再一次访问GetBlogNews2
{ "first": "第一个实例:49538252", "seconed": "第二个实例:49538252" }
得出结论:同一个请求,通过AddTransient注入的对象,在多次使用该对象时,都是同一个实例。(其实好理解,这就是同一个对象_blogNewsService,只不过多次调用罢了)
不同的请求,通过AddTransient注入的对象,在多次使用该对象时,都是同一个实例。只不过不同的http请求,两个对象的实例是不一个。
(3)首先第一次访问GetBlogNews3
{ "first": "第一个实例:2681320", "seconed": "第二个实例:5135072" }
(4)再一次访问GetBlogNews3
{ "first": "第一个实例:59817589", "seconed": "第二个实例:48209832" }
得出结论:同一个请求,通过AddTransient注入的对象,在重新获取注入对象时,是一个新的实例。
不同的请求,通过AddTransient注入的对象,在重新获取注入对象时,是一个新的实例。