(3)ASP.NETCore服务⽣命周期
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 OperationServicewriteline方法的作用
{
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中只实例化⼀次实例,常见的单例模式。
参考⽂献:

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。