ServiceCollection IOC容器 服务的生命周期

- ServiceCollection

   一、Program.cs 注入组件接口服务等

builder.Services.AddSingleton(new AppSettings(builder.Configuration));
builder.Services.AddScoped(typeof(IBaseService<>), typeof(BaseService<>));
builder.Services.AddTransient();

   二、组件的生命周期

  创建测试类

public interface ISqlHelper{
    void GetAll();
}
public class SqlServerHelper : ISqlHelper{
    public void GetAll()
    {
        Console.WriteLine("我被执行");
    }
}

1、Singleton:单例,全局唯一实例 , 配置数据库连接、身份验证、固定缓存等服务

  static void Main(string[] args)
        {
            ServiceCollection services = new ServiceCollection();
            services.AddTransient();
            var provider=services.BuildServiceProvider();
            var sqlHelper=provider.GetService();
            sqlHelper= provider.GetService();

            Console.ReadKey();
        }
            
     输出1次:我被执行

2、Scoped:作用域,在一个作用域中唯一实例,比如在Asp.Net Core应用程序中一次请求相当于一个Scoped

作用域,在一个作用域中唯一实例,比如在Asp.Net Core应用程序中一次请求相当于一个Scoped,但在多个客户端是不同的 在中间件内使用有作用域的服务时,请将该服务注入至 Invoke 或 InvokeAsync 方法。 请不要通过构造函数注入进行注入,因为它会强制服务的行为与单一实例类似。

同一方法访问2次服务,该请求会new1次 例如请求中可能会使用一个数据库上下文来处理数据库相关操作,这时候使用 AddScoped 就可以保证数据库上下文的实例在请求期间是唯一的,从而避免了多个请求之间的冲突和数据错乱 

static void Main(string[] args)
        {
            ServiceCollection services = new ServiceCollection();
            services.AddScoped();
            var provider=services.BuildServiceProvider();
            var scope1=provider.CreateScope();//在一个作用域下创建第一个子作用域
            var sqlHelper= scope1.ServiceProvider.GetService();
            sqlHelper= scope1.ServiceProvider.GetService();
            Console.ReadKey();
        }
        
    结果输出1次:我被执行 这里的scope1 是同一个作用域
static void Main(string[] args)
{
    ServiceCollection services = new ServiceCollection();
    services.AddScoped();
    var provider=services.BuildServiceProvider();
    var scope1=provider.CreateScope();//在一个作用域下创建第一个子作用域
    var scope2= provider.CreateScope();//在一个作用域下创建第二个子作用域
    var sqlHelper= scope1.ServiceProvider.GetService();
    sqlHelper= scope2.ServiceProvider.GetService();

    Console.ReadKey();
}
结果输出2次:我被执行 这里的scope1,scope2 是2个不同的作用域


3、Transient:瞬时,每次的实例都是一个新的对象 

       适用于需要经常创建和销毁的轻型服务。例如,使用 AddTransient 注册日志记录服务可以保证每次日志记录都会创建一个新的实例,从而可以避免在多个请求中共享相同的日志记录器实例导致的数据混乱

        static void Main(string[] args)
        {
            ServiceCollection services = new ServiceCollection();
            services.AddTransient();
var provider=services.BuildServiceProvider();
            var sqlHelper=provider.GetService();
            sqlHelper= provider.GetService();

            Console.ReadKey();
        }
        
       结果会输出2次:我被执行,每次GetService 都会被重新创建


相关文章!