• 重新整理 .net core 实践篇————依赖注入应用之生命法则[三]


    前言

    该章演示依赖注入中,对象的释放行为。

    紧接上文表示,演示:

    services.AddSingleton<IMySingletonService, MySingletonService>();
    services.AddSingleton<IMySingletonService>(new MySingletonService());
    services.AddSingleton<IMySingletonService>(ServiceProvider =>
    {
    	return new MySingletonService();
    });
    

    这三种生命周期的注入方式的不同,他们的生命周期不同。

    主要是两条法则:

    1. DI 只负责释放由其创建的对象实例,DI 在容器或者子容器释放时,释放由其创建的对象的实例。

    2. 不要在根容器中获取瞬时服务,不要在根容器中获取瞬时服务,不要在根容器中获取瞬时服务,重要的事情说三遍。

    正文

    第一条法则证明公理:

    public interface ITestService
    {
    
    }
    
    public class TestService:ITestService,IDisposable
    {
    	public void Dispose()
    	{
    		Console.WriteLine($"DisposableTestService Disposed:{this.GetHashCode()}");
    	}
    }
    

    注册:

    services.AddSingleton<ITestService>(new TestService());
    

    然后测试:

    [HttpGet]
    public int GetService([FromServices] ITestService testService,[FromServices]IHostApplicationLifetime hostApplicationLifetime,[FromQuery]bool stop = false)
    {
    	if (stop)
    	{
    		hostApplicationLifetime.StopApplication();
    	}
    	return 1;
    }
    

    结果:

    应用离开的时候并没有调用我们的Dispose方式。

    那么换一种注册方式:

    services.AddSingleton<ITestService, TestService>();
    

    结果如下:

    应用程序离开的时候会调用我们的dispose。

    再换一种方式:

    services.AddSingleton<ITestService>(serviceProvider =>
    {
         return new TestService();
    });
    

    也会主动调用这个dispose。

    证明不要在根容器中获取瞬时服务:

    理论上离开区域那么应该会调用dispose 释放,但是情况和我们想的不一样。

    测试代码:

    [HttpGet]
    public int GetService([FromServices]IHostApplicationLifetime hostApplicationLifetime,[FromQuery]bool stop = false)
    {
    	if (stop)
    	{
    		hostApplicationLifetime.StopApplication();
    	}
    	return 1;
    }
    

    当访问stop参数不为true


    当访问stop参数为true,也就是关闭服务的时候:

    说明根容器获取的瞬时对象,并没有在离开区域内释放,而是在容器回收的时候才释放。间接的说明一个问题,这个对象起码被我们的根容器间接引用了,这里埋个坑,后面系列解释为什么。

    那么为什么我们从FromServices中获取的ITestService会被释放呢?

    这是应为,其实每一次http访问都会创建一个子容器来保证隔离:

    [HttpGet]
    public int GetService([FromServices]IHostApplicationLifetime hostApplicationLifetime,[FromQuery]bool stop = false)
    {
    	using (IServiceScope scope = HttpContext.RequestServices.CreateScope())
    	{
    		var obj=scope.ServiceProvider.GetService<ITestService>();
    	}
    	if (stop)
    	{
    		hostApplicationLifetime.StopApplication();
    	}
    	return 1;
    }
    

    结果:

    下一节介绍Autofac,主要介绍一下什么情况我们需要使用第三方的Autofac,它给我们带来什么东西,或者给我们带来什么方便,以及如何操作。Autofac 还是比较重要的,一般大一点的项目都会用上,比较方便吧。

    上述只是个人整理,如果错误,望请指教。

  • 相关阅读:
    查看linux命令类型
    理解bashrc和profile[转载]
    问题:ldconfig
    箭头函数
    闭包函数
    方法
    手把手教你使用百度地图(图解)
    变量作用域与解构赋值
    iterable
    Map和Set
  • 原文地址:https://www.cnblogs.com/aoximin/p/14809538.html
Copyright © 2020-2023  润新知