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

    人一定要靠自己
  • 相关阅读:
    Java面向对象
    Java方法
    Java控制语句
    Java接收用户键盘输入
    Java运算符
    Java类型转换
    Java的加载与执行
    Java关键字
    Java常见的DOS命令及JDK
    nginx学习要点记录
  • 原文地址:https://www.cnblogs.com/schangxiang/p/15778056.html
Copyright © 2020-2023  润新知