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依赖注入

(3)ASP.NET Core 服务生命周期的更多相关文章

  1. Asp.Net Core 3.1学习-依赖注入、服务生命周期(6)

    1.前言 面向对象设计(OOD)里有一个重要的思想就是依赖倒置原则(DIP),并由该原则牵引出依赖注入(DI).控制反转(IOC)及其容器等概念.在学习Core依赖注入.服务生命周期之前,下面让我们先 ...

  2. 一图看懂 ASP.NET Core 中的服务生命周期

    翻译自 Waqas Anwar 2020年11月8日的文章 <ASP.NET Core Service Lifetimes (Infographic)> [1] ASP.NET Core ...

  3. 从Asp .net到Asp core (第二篇)《Asp Core 的生命周期》

    前面一篇文章简单回顾了Asp .net的生命周期,也简单提到了Asp .net与Asp Core 的区别,我们说Asp Core不在使用Asp.netRuntime,所以它也没有了web程序生命周期中 ...

  4. ASP.NET 应用程序生命周期概述[转自MSDN]

    本文转自:http://msdn.microsoft.com/zh-cn/library/ms178473(VS.80).aspx 下表描述了 ASP.NET 应用程序生命周期的各个阶段.   阶段 ...

  5. IIS 5.0 和 6.0 的 ASP.NET 应用程序生命周期概述

    本主题概述 ASP.NET 应用程序的生命周期,列出了重要的生命周期事件,并描述了您编写的代码将如何适应于应用程序生命周期.本主题中的信息适用于 IIS 5.0 和 IIS 6.0.有关 IIS 7. ...

  6. [转]ASP.NET应用程序生命周期趣谈(五) IIS7瞎说

    Ps:建议初学者在阅读本文之前,先简要了解一下之前的几篇文章,以便于熟悉本文提到的一些关于IIS6的内容,方便理解.仅供参考. PS:为什么叫瞎说呢?我觉得自己理解的并不到位,只能是作为一个传声筒,希 ...

  7. [转]ASP.NET应用程序生命周期趣谈(四) HttpHandler和页面生命周期

    在之前的三篇文章中,我们还算简明扼要的学习了asp.net的整个生命周期,我们知道了一个Request进来以后先去ISAPI Filter,发现是asp.net程序后又ASPNET_ISAPI.dll ...

  8. [转]ASP.NET应用程序生命周期趣谈(三) HttpModule

    在之前的文章中,我们提到过P_Module(HttpModule)这个能干的程序员哥们儿,它通过在项目经理HttpApplication那里得到的授权,插手整个应用程序级别的事件处理.所有的HttpM ...

  9. [转]ASP.NET应用程序生命周期趣谈(一)

    这几天一直在看ASP.NET应用程序生命周期,真是太难了,我理解起来费了劲了,但偏偏它又是那么重要,所以我希望能给大家带来一篇容易理解又好用的文章来帮助学习ASP.NET应用程序生命周期.这篇就是了. ...

随机推荐

  1. import caffe时出错:can not find module skimage.io

    import caffe时出错:can not find module skimage.io  //以下内容在ubuntu16.4上实际验证过.注意大小写的.----20170605 在命令行输入Py ...

  2. HSSFWorkbook

    public ActionResult excelPrint() { HSSFWorkbook workbook = new HSSFWorkbook();// 创建一个Excel文件 HSSFShe ...

  3. 2016年最值得新手程序猿阅读的书:《增长project师指南》

    这本书的来源于根据我在<Repractise简单介绍篇:Web开发的七天里>中所说的 Web 开发的七个步骤而展开的电子书.当然它也是一个 APP.它一本关于怎样成为增长project师的 ...

  4. java 定义一个同步map内存去重法

    实例:

  5. nginx 安装和配置文件说明

    1. 安装依赖包 yum install gcc gcc+ yum install -y pcre pcre-devel openssl openssl-devel zlib zlib-devel 2 ...

  6. inline-block的使用

    inline-block是什么 inline和block是css中元素display属性的两个选项,而inline-block可以说是介于两者之间的属性值. inline使元素成为内联元素(inlin ...

  7. 图像处理之滤波---gabor

    http://blog.csdn.net/xiaowei_cqu/article/details/24745945 小魏北大

  8. HUD 2031: 进制转换

    进制转换 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submi ...

  9. 网络摄像机IPCamera RTSP直播播放网络/权限/音视频数据/花屏问题检测与分析助手EasyRTSPClient

    前言 最近在项目中遇到一个奇怪的问题,同样的SDK调用,访问海康摄像机的RTSP流,发保活OPTIONS命令保活,一个正常,而另一个一发就会被IPC断开,先看现场截图: 图1:发OPTIONS,摄像机 ...

  10. 基于注解的Sping AOP详解

    一.创建基础业务 package com.kang.sping.aop.service; import org.springframework.stereotype.Service; //使用注解@S ...