当前位置: 移动技术网 > IT编程>开发语言>.net > asp.net core 系列 4 注入服务的生存期

asp.net core 系列 4 注入服务的生存期

2019年01月08日  | 移动技术网IT编程  | 我要评论

梅县二手房,移民加拿大条件,河北工程学院

一.服务的生存期

  在容器中每个注册的服务,根据程序应用需求都可以选择合适的服务生存期,asp.net core 服务有三种生存期配置:

    (1) transient:暂时生存期,在每次请求时被创建。 这种生存期适合轻量级的,无状态的服务。

    (2) scoped: 作用域生存期,在每次请求被创建一次。

    (3) singleton: 单例生存期,在它们第一次被请求时创建。每个后续请求将使用相同的实例。如果应用程序需要单例行为,建议让服务容器管理服务的生命周期,而不是在自己的类中实现单例模式。

   1.1 演示案例

    为了演示生存期和注册选项之间的差异, 以下服务接口,任务是演示标识符 operationid 的操作值变化。 根据为以下接口配置操作服务的生存期的方式,容器在类请求时提供相同或不同的服务实例:

   public interface ioperation
    {
        guid operationid { get; }
    }
    //用于演示暂时生存期
    public interface ioperationtransient : ioperation
    {
    }
    //用于演示作用域生存期
    public interface ioperationscoped : ioperation
    {
    }
    //用于演示单例生存期
    public interface ioperationsingleton : ioperation
    {
    }
    //用于演示单例中空guid
    public interface ioperationsingletoninstance : ioperation
    {
    }

    上面四种服务接口在 operation 类中实现。 调用 operation类时将自动生成一个 guid(如果实例化operation类时没有指定guid),下面是operation类的实现:

 public class operation : ioperationtransient,
     ioperationscoped,
     ioperationsingleton,
     ioperationsingletoninstance
    {
        /// <summary>
        /// 构造方法中生成guid,在实例化类时
        /// </summary>
        public operation() : this(guid.newguid())
        {
        }

        public operation(guid id)
        {
            operationid = id;
        }

        /// <summary>
        /// 获取guid
        /// </summary>
        public guid operationid { get; private set; }
    }

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

    public class operationservice
    {

        public ioperationtransient transientoperation { get; }
        public ioperationscoped scopedoperation { get; }
        public ioperationsingleton singletonoperation { get; }
        public ioperationsingletoninstance singletoninstanceoperation { get; }


        public operationservice(
        ioperationtransient transientoperation,
        ioperationscoped scopedoperation,
        ioperationsingleton singletonoperation,
        ioperationsingletoninstance instanceoperation)
        {
            transientoperation = transientoperation;
            scopedoperation = scopedoperation;
            singletonoperation = singletonoperation;
            singletoninstanceoperation = instanceoperation;
        }
    }

    (1) 如果在请求时创建了临时服务(transient),则 ioperationtransient 服务的 operationid 与 operationservice 的 operationid 不同。 operationservice 将接收 ioperationtransient 类的新实例。 新实例将生成一个不同的 operationid。

    (2) 如果按请求创建有作用域的服务(scoped),则 ioperationscoped 服务的 operationid 与请求中 operationservice 的该 id 相同。 在请求中,两个服务共享不同的 operationid 值。

    (3) 如果单一实例服务(singleton),则只创建一次 并在所有请求和所有服务中使用,则 operationid 在所有服务请求中保持不变。

 

    下面是在 startup.configureservices 服务容器中注册,指定服务的生存期:

            services.addtransient<ioperationtransient, operation>();
            services.addscoped<ioperationscoped, operation>();
            services.addsingleton<ioperationsingleton, operation>();
            services.addsingleton<ioperationsingletoninstance>(new operation(guid.empty));

            services.addtransient<operationservice, operationservice>();

 

    为了演示各个请求中的对象生存期。 下面示例应用 index页面,请求 ioperation 类型和 operationservice。 然后查看operation类属性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 string bindguidmsg { get; set; }
        public void onget()
        {
            bindguidmsg += "ioperation操作: <br/> ";
            bindguidmsg += "暂时性:" + transientoperation.operationid.tostring() + "</br>";
            bindguidmsg += "有作用域:" + scopedoperation.operationid.tostring() + "</br>";
            bindguidmsg += "单一实例:" + singletonoperation.operationid.tostring() + "</br>";
            bindguidmsg += "实例:" + singletoninstanceoperation.operationid.tostring() + "</br>";

            bindguidmsg += "</br></br></br>operationservice操作:</br>";
            bindguidmsg += "暂时性:" + operationservice.transientoperation.operationid.tostring() + "</br>";
            bindguidmsg += "有作用域:" + operationservice.scopedoperation.operationid.tostring() + "</br>";
            bindguidmsg += "单一实例:" + operationservice.singletonoperation.operationid.tostring() + "</br>";
            bindguidmsg += "实例:" + operationservice.singletoninstanceoperation.operationid.tostring() + "</br>";
        }
    }
    <div >
        @{
          @html.raw(@model.bindguidmsg);  
        }
    </div>

 

    第一次index页面请求:

    ioperation 操作:
    暂时性:8ef874a3-743d-4288-98d4-3df126cd940d 
    有作用域:256ff050-f469-4ea3-8dde-16cdd3087c83 
    单一实例:d2caf297-a9b1-4dcf-adda-c68e46fe0741 
    实例:00000000-0000-0000-0000 -000000000000 

    operationservice操作:
    暂时性:5411fd0d-f2e1-4885-beee-2d7ccf48dceb 
    有作用域:256ff050-f469-4ea3-8dde-16cdd3087c83 
    单一实例:d2caf297-a9b1-4dcf-adda-c68e46fe0741 
    实例:00000000-0000-0000- 0000-000000000000

 

    第二次index页面请求:

    ioperation操作:
    暂时性:e685fd0e-d2e0-4900-9eff-e6bc41cd2f80
    有作用域:ca233b49-8326-4a7e-8ee4-6993d70786ed
    单一实例:d2caf297-a9b1-4dcf-adda-c68e46fe0741
    实例:00000000-0000-0000-0000-000000000000

    operationservice操作:
    暂时性:db89be00-c3b7-4f99-bead-5be693ccc2c0
    有作用域:ca233b49-8326-4a7e-8ee4-6993d70786ed
    单一实例:d2caf297-a9b1-4dcf-adda-c68e46fe0741
    实例:00000000-0000-0000-0000-000000000000

 

  下面再总结一下:

    (1)暂时性注册的服务,每次调用服务都会是一个新的服务对象实例。相当于在indexmodel类的局部(方法或属性中)实例化一个依赖对象operation类,伪代码是:

public class indexmodel
{
    public void onget()
        {
//加载index页时,实例化了二次operation类
         //第一次 operationservice operationservice=new operationservice();
         //第二次
         ioperationtransient transientoperation =new operation(); } }

    (2)作用域注册的服务,一次请求内(加载一次index页)对象实例是相同的,但每次请求会产生一个新实例。相当于在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
        }

    (3)单例注册的服务,实例对象对每个对象和每个请求都是相同的。相当于在整个应用application中只实例化一次,常见的单例模式。

 

  参考文献:

    官方文档:asp.net core 

 

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网