07、NetCore2.0插件框架之生命周期

07、NetCore2.0插件框架之生命周期

NetCore2.0插件框架是如何管理插件的生命周期的?生命周期有哪几类,又是在哪些场景下应用的呢?

一、生命周期的分类

我们可以查看系统DI(依赖倒置)开源代码

namespace Microsoft.Extensions.DependencyInjection
{
    public enum ServiceLifetime
    {
        Singleton,
        Scoped,
        Transient
    }
}

从源码可以看出,DI框架支持三种生命周期管理模式

  • Singleton

单例模式,服务在第一次请求时被创建,其后的每次请求都沿用这个已创建的服务。我们不用再自己写单例了。

  • Scoped

     作用域模式,服务在每次请求时被创建,整个请求过程中都贯穿使用这个创建的服务。比如Web页面的一次请求。

  • Transient

   瞬态模式,服务在每次请求时被创建,它最好被用于轻量级无状态服务。

二、重现三种生命周期的应用场景

首先我们创建三个服务,用来提供GUID。

using System;

namespace LifetimeOfDI
{
    public interface IGuidService
    {
        Guid Id();
    }

    public interface ITransientService : IGuidService
    {
    }

    public interface IScopedService : IGuidService
    {
    }

    public interface ISingletonService : IGuidService
    {
    }

    public class GuidServiceBase : IGuidService
    {
        private readonly Guid _item;

        public GuidServiceBase()
        {
            _item = Guid.NewGuid();
        }

        public Guid Id()
        {
            return _item;
        }
    }

    public class TransientService : GuidServiceBase, ITransientService
    {
    }

    public class ScopedService : GuidServiceBase, IScopedService
    {
    }

    public class SingletonService : GuidServiceBase, ISingletonService
    {
    }
}

然后用VS2017新建一个Mvc项目,在Startup类中注册这三个服务

       public void ConfigureServices(IServiceCollection services)
        {
            services.AddTransient<ITransientService, TransientService>();
            services.AddScoped<IScopedService, ScopedService>();
            services.AddSingleton<ISingletonService, SingletonService>();

            services.AddMvc();
        }

既然注册了,在Controller中就可以使用这些服务了,我们采取构造函数注入的方式,来给Controller注入这些服务插件

using Microsoft.AspNetCore.Mvc;

namespace LifetimeOfDI.Controllers
{
    public class HomeController : Controller
    {
        private readonly ITransientService _guidTransientService;
        private readonly IScopedService _guidScopedService;
        private readonly ISingletonService _guidSingletonService;

        // 构造函数注入
        public HomeController(ITransientService guidTransientService,
            IScopedService guidScopedService, ISingletonService guidSingletonService)
        {
            _guidTransientService = guidTransientService;
            _guidScopedService = guidScopedService;
            _guidSingletonService = guidSingletonService;
        }

        public IActionResult Index()
        {
            // 传GUID给页面
            ViewBag.TransientItem = _guidTransientService.Id();
            ViewBag.ScopedItem = _guidScopedService.Id();
            ViewBag.SingletonItem = _guidSingletonService.Id();

            return View();
        }
    }
}

在Index.cshtml页面中显示这三个GUID

@{
    ViewData["Title"] = "Home Page";
}

<div class="row">
    <div>
        <h2>Guid Service Shows</h2>
        <h3>TransientGuid: @ViewBag.TransientItem</h3>
        <h3>ScopedGuid: @ViewBag.ScopedItem</h3>
        <h3>SingletonGuid: @ViewBag.SingletonItem</h3>
    </div>
</div>

我们启动两个浏览器,可以看出单例模式的Guid在两个浏览器这种是一致的,而且,并且刷新浏览器,也不会改变;另外两个因为每次刷新都发起了一次新的请求,所以Guid都不同。

三、使用局部页面技术验证作用域生命周期的特点

上一节没能验证Scoped类型生命周期,因为每次刷新都发起了一次新的请求。我们需要验证一个Web请求,对服务的多次使用。如何验证呢?这里我们借助局部页面技术。

新建一个局部页面IndexPartial.cshtml,在局部页面中引用我们的自定义服务命名空间,并注入三个服务,分别显示其Id。

@*引用自定义接口的命名空间*@
@using LifetimeOfDI

@*依赖注入*@
@inject ITransientService TransientService
@inject IScopedService ScopedService
@inject ISingletonService SingletonService

@*输出服务提供的Id*@
<div class="row">
    <div>
        <h2>Guid Service Shows</h2>
        <h3>TransientGuid: @TransientService.Id()</h3>
        <h3>ScopedGuid: @ScopedService.Id()</h3>
        <h3>SingletonGuid: @SingletonService.Id()</h3>
    </div>
</div>

Index.cshtml页面中两次引用这个局部页,这样就可以展示,一次请求两次调用服务接口的场景。

@{
    ViewData["Title"] = "Home Page";
}

@Html.Partial("IndexPartial")
@Html.Partial("IndexPartial")

看看效果吧

从效果看,作用域生命周期内的Id在一次请求的多次调用中保持了一致性;而瞬态声明周期的则每次调用都不同;单例声明周期的则不用说了,不同请求的多次调用都不变,更不用说相同请求了。

至此,我们理解了三种生命周期的的特点,在业务开发中可以按需使用了。  

时间: 2024-08-28 15:40:15

07、NetCore2.0插件框架之生命周期的相关文章

05、NetCore2.0插件框架运行原理源码初窥

05.NetCore2.0插件框架运行原理之WebHostBuilder源码初窥 NetCore2.0的插件框架是要解决对象创建的问题,把创建对象与使用对象进行解耦.调用者不需要关心对象是单例的还是多实例的:插件的扩展和调用也更容易. 一.我们先看看插件框架是如何使用的 首先使用VS2017新建一个控制台程序,要使用插件框架,我们需要引入微软的依赖注入包: install-package Microsoft.Extensions.DependencyInjection 我们声明一个自己的接口,并

Tomcat7.0源码分析——生命周期管理

前言 从server.xml文件解析出来的各个对象都是容器,比如:Server.Service.Connector等.这些容器都具有新建.初始化完成.启动.停止.失败.销毁等状态.tomcat的实现提供了对这些容器的生命周期管理,本文将通过对Tomcat7.0的源码阅读,深入剖析这一过程. Tomcat生命周期类接口设计 我们先阅读图1,从中了解Tomcat涉及生命周期管理的主要类. 图1 Tomcat生命周期类接口设计 这里对图1中涉及的主要类作个简单介绍: Lifecycle:定义了容器生命

【Android开发学习笔记】【高级】【随笔】插件化——Activity生命周期

前言 如同第一章我们说的,宿主程序通过 dexclassloader 将插件的类加载进来,然后通过反射去调用它的方法,这样Activity就被当成了一个普通的类来执行了,因此系统不再接管它的生命周期,也就是说Activity的生命周期函数失效了.针对这样的问题,有网友想出使用Fragment来解决此问题,Fragment既有类似于Activity的生命周期,又有类似于View的界面,因此选它比较合适,具体的做法是将Fragment加入到宿主的代理Activity内部,其生命周期将完全由代理Act

面试-Django框架请求生命周期

先看一张图吧! 1.请求生命周期 - wsgi, 他就是socket服务端,用于接收用户请求并将请求进行初次封装,然后将请求交给web框架(Flask.Django) - 中间件,帮助我们对请求进行校验或在请求对象中添加其他相关数据,例如:csrf.request.session - 路由匹配 - 视图函数,在视图函数中进行业务逻辑的处理,可能涉及到:orm.templates => 渲染 - 中间件,对响应的数据进行处理. - wsgi,将响应的内容发送给浏览器. 2.什么wsgi wsgi:

深入了解asp.net框架。生命周期以及事件处理机制

刚接触asp.net框架觉得很好奇.他的快速开发是怎么实现的.控件的状态又是怎么保持的.我们都知道http是无状态的.而且网上很多人都说使用asp.net框架使用服务器框架是非常慢的. 带着这些疑问我们来了解asp.net框架吧 我们先来简单说一下asp.net框架的执行过程 当浏览器发送一个请求 比如请求index.aspx 的页面 到底经过了哪些事情 1.首先客户端会组织请求报文发送到iis服务器 2.iis服务器通过文件后缀到扩展程序映射找到对应的处理程序即,这里这是asp.net_isa

vue2.0学习笔记之生命周期

beforeCreate 组件实例刚刚被创建,属性都没有 created  实例已经创建完成,属性已经绑定 beforeMount 模板编译之前 mounted 模板编译之后,代替之前ready beforeUpdate        组件更新之前 updated                 组件更新完毕 beforeDestroy       组件销毁前 destroyed              组件销毁后 <!DOCTYPE html> <html lang="en

Maven3生命周期和插件

生命周期 Maven的生命周期是通过大量的项目和工具的学习和反思,然后总结出来的一套完善和易扩展的流程,包含了项目的清理.初始化.编译.测试.打包.集成测试.验证.部署和发布站点等几乎所有的构建步骤:同时,Maven的生命周期是抽象的,它只是定义了一系列的生命周期以及生命周期的执行顺序,而具体每个生命周期的处理逻辑由Maven插件提供. Maven共有三套生命周期: clean周期:主要是用来清理项目 default周期:主要是用来构建项目 site周期:主要是用来发布项目站点 每个周期中都包含

Maven学习(四):生命周期与maven插件

一.maven 生命周期 (一)简介 Maven强大的一个重要的原因是它有一个十分完善的生命周期模型(lifecycle),这个生命周期可以从两方面来理解: 1.顾名思义,运行Maven的每个步骤都由它来定义的,这种预定义的默认行为使得我们使用Maven变得简单,相比而言,Ant的每个步骤都要你手工去定义. 2.这个模型是一种标准,在不同的项目中,使用Maven的接口是一样的,这样就不用去仔细理解每个项目的构建了,一般情况下,mvn clean install  这样的命令是通用的. 3.一个M

【读书笔记】《Maven实战》 第7章 生命周期与插件

7.1什么是生命周期 软件开发人员每天都在对项目进行清理.编译.测试及部署,Maven生命周期是对所有构建过程进行抽象和统一,含项目的清理.初始化.编译.测试.打包.集成测试.验证.部署和站点生成等几乎所有构建步骤. 7.2生命周期详解 7.2.1三套相互独立的生命周期 clean:目的是清理项目 default:目的是构建项目 site:目的是建立项目站点 两个原则 a)三套生命周期相互独立,不会相互影响 b)每个生命周期包含一些阶段(phase),阶段间有顺序且后面的阶段依赖于前面的阶段 7