首先我们在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

相关文章:

  • 2021-10-10
  • 2021-12-22
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-11-01
  • 2021-12-01
猜你喜欢
  • 2022-12-23
  • 2021-09-12
  • 2021-05-22
  • 2022-12-23
  • 2021-06-03
  • 2022-12-23
  • 2021-07-07
相关资源
相似解决方案