在ConfigureServices方法中的容器注册每个应用程序的服务,Asp.Core都可以为每个应用程序提供三种服务生命周期:
Transient(暂时):每次请求都会创建一个新的实例。这种生命周期最适合轻量级,无状态服务。Scoped(作用域):在同一个作用域内只初始化一个实例 ,可以理解为每一个请求只创建一个实例,同一个请求会在一个作用域内。Singleton(单例):整个应用程序生命周期以内只创建一个实例,后续每个请求都使用相同的实例。如果应用程序需要单例行为,建议让服务容器管理服务的生命周期,而不是在自己的类中实现单例模式。为了演示生命周期和注册选项之间的差异,请考虑以下接口,将任务表示为具有唯一标识符 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服务生命周期的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持一聚教程网。