07、NetCore2.0依赖注入(DI)之生命周期

NetCore2.0依赖注入框架(DI)是如何管理注入对象的生命周期的?生命周期有哪几类,又是在哪些场景下应用的呢?

------------------------------------------------------------------------------------------------------------

写在前面:这是一个系列的文章,总目录请移步: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在一次请求的多次调用中保持了一致性;而瞬态生命周期则每次调用都不同;单例生命周期则不用说了,不同请求的多次调用都不变,更不用说相同请求了。

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

07、NetCore2.0依赖注入(DI)之生命周期的更多相关文章

  1. 05、NetCore2.0依赖注入(DI)之Web应用启动流程管理

    05.NetCore2.0依赖注入(DI)之Web应用启动流程管理 在一个Asp.net core 2.0 Web应用程序中,启动过程都做了些什么?NetCore2.0的依赖注入(DI)框架是如何管理 ...

  2. 06、NetCore2.0依赖注入(DI)之整合Autofac

    06.NetCore2.0依赖注入(DI)之整合Autofac 除了使用NetCore2.0系统的依赖注入(DI)框架外,我们还可以使用其他成熟的DI框架,如Autofac.Unity等.只要他们支持 ...

  3. Yii2.0 依赖注入(DI)和依赖注入容器的原理

    依赖注入和依赖注入容器 为了降低代码耦合程度,提高项目的可维护性,Yii采用多许多当下最流行又相对成熟的设计模式,包括了依赖注入(Denpdency Injection, DI)和服务定位器(Serv ...

  4. .Net Core3.0依赖注入DI

    构建ASP.NET Core应用程序的时候,依赖注入已成为了.NET Core的核心,这篇文章,我们理一理依赖注入的使用方法. 不使用依赖注入 首先,我们创建一个ASP.NET Core Mvc项目, ...

  5. .netCore2.0 依赖注入

    依赖注入(ID)是一种实现对象及其合作者或者依赖想之间松散耦合的技术对于传统的方法来说,获取类的方法通常用new如下 public class DIController : Controller { ...

  6. Console app 里的依赖注入及其实例生命周期

    依赖注入是 ASP.NET Core 里的核心概念之一,我们平常总是愉快地在Startup类的ConfigureServices方法里往IServiceCollection里注册各种类型,以致有一些同 ...

  7. ADO.NET .net core2.0添加json文件并转化成类注入控制器使用 简单了解 iTextSharp实现HTML to PDF ASP.NET MVC 中 Autofac依赖注入DI 控制反转IOC 了解一下 C# AutoMapper 了解一下

    ADO.NET   一.ADO.NET概要 ADO.NET是.NET框架中的重要组件,主要用于完成C#应用程序访问数据库 二.ADO.NET的组成 ①System.Data  → DataTable, ...

  8. 轻松学,浅析依赖倒置(DIP)、控制反转(IOC)和依赖注入(DI) 依赖注入和控制反转的理解,写的太好了。

    轻松学,浅析依赖倒置(DIP).控制反转(IOC)和依赖注入(DI) 2017年07月13日 22:04:39 frank909 阅读数:14269更多 所属专栏: Java 反射基础知识与实战   ...

  9. spring-framework-中文文档三:依赖注入DI

    5.4依赖性 典型的企业应用程序不包含单个对象(或Spring的说法中的bean).即使最简单的应用程序也有几个对象一起工作来展示最终用户将其视为一个连贯的应用程序.下一节将介绍如何从定义许多独立的b ...

随机推荐

  1. Redis初识、设计思想与一些学习资源推荐

    一.Redis简介 1.什么是Redis Redis 是一个开源的使用ANSI C 语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value 数据库,并提供多种语言的API.从2010 年 ...

  2. JavaScript模板引擎artTemplate.js——两种方法实现性别的判定

    template.helper(name, callback) name:必传,辅助事件的名称. callback:必传,辅助事件的回调函数. return:undefined 所谓的辅助事件,主要用 ...

  3. jQuery概述

    JQUERY   JS语法字典---网友总结 1.document.write(""); 输出语句2.JS中的注释为//3.传统的HTML文档顺序是:document->ht ...

  4. 优化MySchool数据库(三)

    使用T_SQL 编写业务逻辑: 如何定义及使用“变量”: ---- 让电脑帮我记住一个名字(王二) C#: string   name ;    [定义一个变量] name = "王二&qu ...

  5. Linux系统入门学习:在curl中设置自定义的HTTP头

    http://www.linuxidc.com/Linux/2015-02/114220.htm

  6. QueryRunner(common-dbutils.jar)

    QueryRunner update方法:* int update(String sql, Object... params) --> 可执行增.删.改语句* int update(Connec ...

  7. oracle小数点前零丢失的问题

    1.问题起源        oracle  数据库 字段值为小于1的小数时,使用char类型处理,会丢失小数点前面的0        例如0.2就变成了.2 2.解决办法: (1)用to_char函数 ...

  8. Editing and Deleting Data

    Editing and Deleting Data In the previous chapter we've come to learn how we can use the zend-form a ...

  9. leetcode之 median of two sorted arrays

    这是我做的第二个leetcode题目,一开始以为和第一个一样很简单,但是做的过程中才发现这个题目非常难,给人一种“刚上战场就踩上地雷挂掉了”的感觉.后来搜了一下leetcode的难度分布表(leetc ...

  10. cocos2d-x 3.x 橡皮擦功能

    1.HelloWorldScene.h cocos2d::DrawNode* _eraser; cocos2d::RenderTexture*_renderTexture; 2.HelloWorldS ...