在asp.net core中DI的概念是由这几部分组成的:

IServiceCollection,保存IServiceDescriptor实例的列表

IServiceProvider,只有一个方法GetService,用来获取服务。ServiceProvider由一个Scope的概念,是通过CreateScope(它又调用了IServiceScopeFactory)来创建一个IServiceScope,这个IServceScope中包含一个新创建的IserviceProvider。

IServiceDescriptor,用来描述服务,包括service type,Implementation type,service life time.

ServiceLifeTime,描述服务的生命周期,有三种生命周期:

Singleton

Scope

Transient

DI就是由上述这四个主要的类型外加一大堆扩展方法而形成的。

ServiceProvider作为DI容器,内部维护一个已注册服务的列表,第一个产生的ServiceProvider叫做根容器,通过它创建的容器叫做子容器,所有创建的ServiceProvider都共享这个已注册服务的列表。

三种生命周期的注册方式也主要是通过将服务注册在根容器还是子容器来达到目的的。并且,如果一个服务实现了IDisposable接口,相应的,容器也会负责调用服务的Dispose方法。也就说,服务注册在哪里,哪里就服务销毁它。

Singleton

单例模式。IServiceProvider作为DI容器,单例模式的服务会被注册到根容器上面。它的生命周期会随根容器的销毁而销毁,也就是说,应用程序停掉了它才会销毁。

Scope

Scope实际上是由一个IServiceScope接口来描述的,上面有写,它是由ServiceProvider的一个扩展方法CreateScope来实现的,内部由IserviceScopeFacrory来最终生成一个Scope,这个Scope生成的时候会创建一个新的ServiceProvider,利用新生成的ServiceProvider来提供的服务也就形成了一个Scope的概念。顺便插一句,任何一个ServiceProvider都由一个根容器的引用,所以的Provider都引用了同一个根容器。它的生命周期随创建它的ServiceProvider的销毁而销毁,在asp.net core里面,当客户端发起请求时,都会新创建一个Scope,然后都是利用这个新创建的Scope中的ServiceProvider属性来提供服务的。

Transient

随用随取,用完就销毁。它的生命周期通Scope,都是随创建它的ServiceProvider的销毁而销毁。

Scope的特殊说明

一般情况下,生命周期较长的服务不应该依赖一个生命周期较短的服务,BuildServiceProvider方法可以传入一个bool类型的参数,这个参数解决了这么一个问题:

举个例子,比方说在asp.net core项目中我们使用entity framework core,要添加一个DbContext,这个DbContext是被添加成Scope生命周期的,也就是说它会随着请求的发起创建,请求结束后消亡。但是如果他被一个Singleton的服务所依赖/引用,那么它的生命周期就会变成Singleton。这个连接永远都不会释放,当许多请求过来的时候,数据库的连接池的连接就会变得不够用。这本身是一种错误的实践,避免这样的错误就是在BuilServiceProvider这个方法中传入一个true的bool值,只是DI在注入服务的时候要判断Scope的服务是否被错误的使用,一般来说错误的使用有两种情况:

第一种情况是用根ServiceProvider来创建一个Scope的服务。在根容器上面创建的服务会由根容器来负责销毁,那么也就是说,Scope的服务也就变成了Singleton的了。因为根容器只有在应用程序停止运行的时候才会销毁。

第二种情况是Scope的服务被Singleton的服务依赖/引用。那么这个Scope的服务也会随依赖它的Singleton服务变成Singleton的。

Asp.Net Core中DI的知识总结的更多相关文章

  1. 浅谈ASP.NET Core中的DI

    DI的一些事 传送门马丁大叔的文章 什么是依赖注入(DI: Dependency Injection)?     依赖注入(DI)是一种面向对象的软件设计模式,主要是帮助开发人员开发出松耦合的应用程序 ...

  2. ASP.NET Core中的依赖注入(2):依赖注入(DI)

    IoC主要体现了这样一种设计思想:通过将一组通用流程的控制从应用转移到框架之中以实现对流程的复用,同时采用"好莱坞原则"是应用程序以被动的方式实现对流程的定制.我们可以采用若干设计 ...

  3. ASP.NET Core中的ActionFilter与DI

    一.简介 前几篇文章都是讲ASP.NET Core MVC中的依赖注入(DI)与扩展点的,也许大家都发现在ASP.NET CORE中所有的组件都是通过依赖注入来扩展的,而且面向一组功能就会有一组接口或 ...

  4. 浅谈ASP.NET Core中IOC与DI的理解和使用

    说起IOC和DI,使用过ASP.NET Core的人对这两个概念一定不陌生,早前,自己也有尝试过去了解这两个东西,但是一直觉得有点很难去理解,总觉得对其还是模糊不清,所以,趁着今天有空,就去把两个概念 ...

  5. ASP.NET Core Web 应用程序系列(三)- 在ASP.NET Core中使用Autofac替换自带DI进行构造函数和属性的批量依赖注入(MVC当中应用)

    在上一章中主要和大家分享了在ASP.NET Core中如何使用Autofac替换自带DI进行构造函数的批量依赖注入,本章将和大家继续分享如何使之能够同时支持属性的批量依赖注入. 约定: 1.仓储层接口 ...

  6. ASP.NET Core Web 应用程序系列(二)- 在ASP.NET Core中使用Autofac替换自带DI进行批量依赖注入(MVC当中应用)

    在上一章中主要和大家分享在MVC当中如何使用ASP.NET Core内置的DI进行批量依赖注入,本章将继续和大家分享在ASP.NET Core中如何使用Autofac替换自带DI进行批量依赖注入. P ...

  7. Asp.Net Core 中利用QuartzHostedService 实现 Quartz 注入依赖 (DI)

    QuartzHostedService  是一个用来在Asp.Net Core 中实现 Quartz 的任务注入依赖的nuget 包: 基本示例如下: using System; using Syst ...

  8. 在Asp.Net Core中使用中间件保护非公开文件

    在企业开发中,我们经常会遇到由用户上传文件的场景,比如某OA系统中,由用户填写某表单并上传身份证,由身份管理员审查,超级管理员可以查看. 就这样一个场景,用户上传的文件只能有三种人看得见(能够访问) ...

  9. C# 嵌入dll 动软代码生成器基础使用 系统缓存全解析 .NET开发中的事务处理大比拼 C#之数据类型学习 【基于EF Core的Code First模式的DotNetCore快速开发框架】完成对DB First代码生成的支持 基于EF Core的Code First模式的DotNetCore快速开发框架 【懒人有道】在asp.net core中实现程序集注入

    C# 嵌入dll   在很多时候我们在生成C#exe文件时,如果在工程里调用了dll文件时,那么如果不加以处理的话在生成的exe文件运行时需要连同这个dll一起转移,相比于一个单独干净的exe,这种形 ...

随机推荐

  1. 网络协议 16 - DNS 协议:网络世界的地址簿

    [前五篇]系列文章传送门: 网络协议 11 - Socket 编程(下):眼见为实耳听为虚 网络协议 12 - HTTP 协议:常用而不简单 网络协议 13 - HTTPS 协议:加密路上无尽头 网络 ...

  2. 实体继承与@Builder注解共存

    在面向对象的设计里,继承是非常必要的,我们会把共有的属性和方法抽象到父类中,由它统一去实现,而在进行lombok时代之后,更多的打法是使用@Builder来进行对象赋值,我们直接在类上加@Builde ...

  3. ERROR 2003 (HY000): Can't connect to MySQL server on 'localhost' (10061)解决办法

    一,报错原因及分析 mysql的这个报错的原因是mysql服务没有正确启动就是mysqld这个程序. mysql要想运行需要mysql和mysqld两个都启动才行 二,解决办法 右键我的电脑——> ...

  4. SmartSql Cache标签

    Demo <Cache Id="T_Test.LruCache" Type="Lru"> <Parameter Key="Cache ...

  5. js获取url 中的值,并跳转相应页面

    实现方法:一:获取URL带QUESTRING参数的JAVASCRIPT客户端解决方案,相当于asp的request.querystring,PHP的$_GET1.函数: <Script lang ...

  6. Javascript 面向对象(共有方法,私有方法,特权方法,静态属性和方法,静态类)示例讲解

    一,私有属性和方法 私有方法:私有方法本身是可以访问类内部的所有属性(即私有属性和公有属性),但是私有方法是不可以在类的外部被调用. <script> /* * 私有方法:私有方法本身是可 ...

  7. 解决Windows对JDK默认版本切换问题

    注意修改path路径,或者修改控制面板下的java控制面板并不有效,原因是由于在WINDOWS\System32环境变量中的优先级高于JAVA_HOME设置的环境变量优先级,故如果只修改环境变量JAV ...

  8. VS code 设置中文后也显示英文的问题

    按f1 搜索 Configore Display Language 设置 zh-cn 关闭软件重启. 如果重启菜单等还是英文的,在商店查看已安装的插件,把中文插件重新安装一遍,然后重启软件.

  9. Django 使用 locals() 函数

    locals() 函数会以字典类型返回当前位置的全部局部变量. 在 views.py 中添加 from django.shortcuts import render,HttpResponse,rend ...

  10. OPPO K3在哪里打开USB调试模式的完美方法

    当我们使用pc链接安卓手机的时候,如果手机没有开启USB调试模式,pc则无法成功识别我们的手机,这个时候我们需要找解决方法将手机的USB调试模式打开,今天我们介绍OPPO K3如何开启USB调试模式的 ...