.net core 依赖注入的三个生命周期理解

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注入的对象,在重新获取注入对象时,是一个新的实例。

人一定要靠自己
原文地址:https://www.cnblogs.com/schangxiang/p/15778056.html