• (3)ASP.NET Core2.2 服务生命周期


    1.前言

    在ConfigureServices方法中的容器注册每个应用程序的服务,Asp.Core都可以为每个应用程序提供三种服务生命周期:
    ●Transient(暂时):每次请求都会创建一个新的实例。这种生命周期最适合轻量级,无状态服务。
    ●Scoped(作用域):在同一个作用域内只初始化一个实例 ,可以理解为每一个请求只创建一个实例,同一个请求会在一个作用域内。
    ●Singleton(单例):整个应用程序生命周期以内只创建一个实例,后续每个请求都使用相同的实例。如果应用程序需要单例行为,建议让服务容器管理服务的生命周期,而不是在自己的类中实现单例模式。

    2.服务生命周期与注册选项案例演示

    为了演示生命周期和注册选项之间的差异,请考虑以下接口,将任务表示为具有唯一标识符 OperationId 的操作。根据以下接口配置操作服务的生命周期的方式,容器在类请求时提供相同或不同的服务实例:

    public interface IOperation
    {
        Guid OperationId { get; }
    }
    public interface IOperationTransient : IOperation
    {
    }
    public interface IOperationScoped : IOperation
    {
    }
    public interface IOperationSingleton : IOperation
    {
    }
    public interface IOperationSingletonInstance : IOperation
    {
    }

    上面四种服务接口在 Operation 类中实现。调用Operation类时将自动生成一个GUID,下面是Operation类的实现:

    public class Operation : IOperationTransient, IOperationScoped, IOperationSingleton, IOperationSingletonInstance
    {
        public Operation() : this(Guid.NewGuid())
        {
        }
        public Operation(Guid id)
        {
            OperationId = id;
        }
        public Guid OperationId { get; private set; }
    }

    再注册一个OperationService服务实例,当通过依赖关系注入请求 OperationService 实例时,它将接收每个服务的新实例或基于从属服务(Operation)的生命周期的现有实例。OperationService 服务作用就是第二次调用 Operation类,查看Operation类实例的作用域变化。

    public class OperationService
    {
        public OperationService(
            IOperationTransient transientOperation,
            IOperationScoped scopedOperation,
            IOperationSingleton singletonOperation,
            IOperationSingletonInstance instanceOperation)
        {
            _transientOperation = transientOperation;
            _scopedOperation = scopedOperation;
            _singletonOperation = singletonOperation;
            _singletonInstanceOperation = instanceOperation;
        }
        public IOperationTransient _transientOperation { get; }
        public IOperationScoped _scopedOperation { get; }
        public IOperationSingleton _singletonOperation { get; }
        public IOperationSingletonInstance _singletonInstanceOperation { get; }
    }

    然后在Startup.ConfigureServices()服务容器中注册各个生命周期的实例:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddTransient<IOperationTransient, Operation>();
        services.AddScoped<IOperationScoped, Operation>();
        services.AddSingleton<IOperationSingleton, Operation>();
        services.AddSingleton<IOperationSingletonInstance>(new Operation(Guid.Empty));
        // OperationService depends on each of the other Operation types.
        services.AddTransient<OperationService, OperationService>();
    }

    再在IndexModel模块里面调用OnGet方法输出,观察IOperation与OperationService类属性OperationId 值的变化:

    public class IndexModel : PageModel
    {
        public OperationService _operationService { get; }
        public IOperationTransient _transientOperation { get; }
        public IOperationScoped _scopedOperation { get; }
        public IOperationSingleton _singletonOperation { get; }
        public IOperationSingletonInstance _singletonInstanceOperation { get; }
        public IndexModel(
        OperationService operationService,
        IOperationTransient transientOperation,
        IOperationScoped scopedOperation,
        IOperationSingleton singletonOperation,
        IOperationSingletonInstance singletonInstanceOperation)
        {
            _operationService = operationService;
            _transientOperation = transientOperation;
            _scopedOperation = scopedOperation;
            _singletonOperation = singletonOperation;
            _singletonInstanceOperation = singletonInstanceOperation;
        }
        public void OnGet()
        {
            Console.WriteLine("IOperation操作:");
            Console.WriteLine("暂时:" + _transientOperation.OperationId.ToString());
            Console.WriteLine("作用域:" + _scopedOperation.OperationId.ToString());
            Console.WriteLine("单例:" + _singletonOperation.OperationId.ToString());
            Console.WriteLine("实例:" + _singletonInstanceOperation.OperationId.ToString());
            Console.WriteLine("OperationService操作:");
            Console.WriteLine("暂时:" + _operationService._transientOperation.OperationId.ToString());
            Console.WriteLine("作用域:" + _operationService._scopedOperation.OperationId.ToString());
            Console.WriteLine("单例:" + _operationService._singletonOperation.OperationId.ToString());
            Console.WriteLine("实例:" + _operationService._singletonInstanceOperation.OperationId.ToString());
        }
    }

    执行IndexModel 类输出结果:

    由图总结如下:
    2.1 Transient(暂时):每次调用服务的时候都会创建一个新的实例。即在IndexModel类的局部方法或属性中(这里是OnGet方法)实例化一个依赖对象Operation类,伪代码是:

    public class IndexModel: PageModel
    {
        public void OnGet()
        {
              //调用IndexModel类时,实例化了两次Operation类
          //第一次
              OperationService operationService=new OperationService();
         //第二次
         IOperationTransient TransientOperation=new Operation();
        }
    }

    2.2 Scoped(作用域):一次请求(Action)内对象实例是相同的,但每次请求会产生一个新实例。相当于在IndexModel类的全局中实例化一次依赖对象Operation类,伪代码是:

    OperationService operationService = null;
    public IndexModel()
    {
        operationService = new OperationService();
        operationService._scopedOperation = new Operation();
    }
    public void OnGet()
    {
        operationService._scopedOperation.OperationId;
        IOperationScoped operationScoped = operationService._scopedOperation;
        operationScoped.OperationId
    }

    2.3 Singleton(单例):首次请求初始化同一个实例,后续每次请求都使用同一个实例。相当于在整个应用Application中只实例化一次实例,常见的单例模式。

    参考文献:
    在ASP.NET Core依赖注入

  • 相关阅读:
    Caliburn.Micro框架之Bindings
    Excel批量插入的SQL Server
    简单的物流项目实战,WPF的MVVM设计模式(五)
    简单的物流项目实战,WPF的MVVM设计模式(四)
    简单的物流项目实战,WPF的MVVM设计模式(三)
    简单的物流项目实战,WPF的MVVM设计模式(二)
    简单的物流项目实战,WPF的MVVM设计模式(一)
    系统架构——负载均衡整理总结
    .NET知识梳理——8.AOP
    .NET知识梳理——7.Linq
  • 原文地址:https://www.cnblogs.com/wzk153/p/10897826.html
Copyright © 2020-2023  润新知