.NET Core 对象( Transient、Scope、Singleton )生命周期详解 (对象创建以及释放)

首先我们在VS2019中创建一个.NET Core的控制台程序,方便演示;

需要安装两个依赖包

Microsoft.Extensions.DependencyInjection 依赖注入对象的具体实现

Microsoft.Extensions.DependencyInjection.Abstractions 依赖注入对象的抽象

Part 1 : AddTransient AddScoped AddSingleton

话不多说,看以下Demo的代码以及运行结果 

  public static class Demo
    {
        public interface IAccount { }
        public interface IMessage { }
        public interface ITool { }
        public class Base
        {
            public Base()
            {
                Console.WriteLine($"{GetType().Name} Created");
            }
        }
        public class Account : Base,IAccount { }
        public class Message : Base, IMessage { }
        public class Tool : Base, ITool { }

        public static void Run()
        {
            Console.WriteLine("Run Method Begin...");
            //root provider
            var rootProvider = new ServiceCollection()
                .AddTransient<IAccount, Account>()
                .AddScoped<IMessage, Message>()
                .AddSingleton<ITool, Tool>()
                .BuildServiceProvider();
            //create child provider
            var childProvider1 = rootProvider.CreateScope().ServiceProvider;
            var childProvider2 = rootProvider.CreateScope().ServiceProvider;

            GetService<IAccount>(childProvider1);
            GetService<IMessage>(childProvider1);
            GetService<ITool>(childProvider1);
            Console.WriteLine();
            GetService<IAccount>(childProvider2);
            GetService<IMessage>(childProvider2);
            GetService<ITool>(childProvider2);
            Console.WriteLine("Run Method End...");

        }

        public static void GetService<T>(IServiceProvider serviceProvider)
        {
            serviceProvider.GetService<T>();
            serviceProvider.GetService<T>();
        }
        

    }

调用Demo.Run() 输出结果

Run Method Begin...
Account Created
Account Created
Message Created
Tool Created

Account Created
Account Created
Message Created
Run Method End...
调用GetService<T>方法获取实例进行实例的创建,Account、Message、Tool都继承了Base类,因此在被创建时,会调用Base类的构造函数;
AddTransient => 每次请求都会创建一个新的实例
可以看到子容器childProvider1Account对象被创建了两次,因为可以看出AddTransient每次请求时都会创建一个新的实例;
AddScoped => 同一个请求中返回同一个实例

在子容器的作用域中进行查找,同一个子容器中只会创建一次;所以childProvider1中调用两次GetService()方法只创建一次实列;
childProvider2也只创建了一次Message

AddSingleton => 整个应用程序只会创建一次;单例永远从根容器rootProvider中查找
Tool 因为是Singleton 类型,因此整个程序中只创建了一次;

Part 2 : IDisposable

第二部分我们来看看创建的这些对象是何时进行释放的

在以上的代码中,将Base类实现IDisposable接口

public class Base : IDisposable
        {
            public Base()
            {
                Console.WriteLine($"{GetType().Name} Created");
            }

            public void Dispose()
            {
                Console.WriteLine($"{GetType().Name} Disposed");
            }
        }

在Run方法中使用Using来测试结果:

public static void Run()
        {
            //root provider
            using (ServiceProvider root = new ServiceCollection()
                .AddTransient<IAccount, Account>()
                .AddScoped<IMessage, Message>()
                .AddSingleton<ITool, Tool>()
                .BuildServiceProvider())
            {
                using (var scope = root.CreateScope())
                {
                    var child = scope.ServiceProvider;
                    child.GetService<IAccount>();
                    child.GetService<IMessage>();
                    child.GetService<ITool>();
                    Console.WriteLine("Child provider begin dispose");
                }
                Console.WriteLine("Child provider disposed  ");
                Console.WriteLine("Root provider begin dispose  ");

            }
            Console.WriteLine("Root provider disposed  ");
        }
View Code

测试结果

Account Created
Message Created
Tool Created
Child provider begin dispose
Message Disposed
Account Disposed
Child provider disposed
Root provider begin dispose
Tool Disposed
Root provider disposed

可以看出 AddTransient 和 AddScoped 在使用完child容器后,就调用了Base的 Dispose() ;而 AddSingle则在使用完root容器后再释放的;

 

posted @ 2020-12-10 16:30  待我身高一米八  阅读(1865)  评论(1编辑  收藏  举报