欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

(3)Asp.Net Core 服务生命周期

程序员文章站 2022-07-10 23:54:38
1.前言 在ConfigureServices方法中的容器注册每个应用程序的服务,Asp.Core都可以为每个应用程序提供三种服务生命周期:●Transient(暂时):每次请求都会创建一个新的实例。这种生命周期最适合轻量级,无状态服务。●Scoped(作用域):在同一个作用域内只初始化一个实例 , ......

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 类输出结果:

(3)Asp.Net Core 服务生命周期

由图总结如下:
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依赖注入