ASP.NET Core 中的依赖注入

什么是依赖注入

软件设计原则中有一个依赖倒置原则(DIP),为了更好的解耦,讲究要依赖于抽象,不要依赖于具体。而控制反转(Ioc)就是这样的原则的其中一个实现思路, 这个思路的其中一种实现方式就是依赖注入(DI)。

  • 什么是依赖:当一个类需要另一个类协作来完成工作的时候就产生了依赖。

  • 什么是注入: 注入体现的是一个IOC(控制反转的的思想)。正转是自己来实例化需要的依赖。反转是类不应该自己创建它,而是应该由它的调用者传给它。于是可以通过构造函数等让外界把依赖传给类。

  • 为什么要反转 为了在业务变化的时候尽少改动代码可能造成的问题。基于抽象添加新的实现。只需要在原来注入的地方改一下就可以了。

  • 什么是容器 容器统一管理系统中的所有依赖。容器负责两件事情:

    640?wx_fmt=png

    • 绑定服务与实例之间的映射关系

    • 获取实例并对实例进行管理(创建与销毁)

ASP .NET Core 中使用依赖注入

640?wx_fmt=png

  • IServiceCollection 负责注册服务,是一个IList

  • IServiceProvider 负责提供实例,是由IServiceCollection的扩展方法BuildServiceProvider创建的。

  • ServiceDescriptor 单个服务描述

    • Type ServiceType: 服务的类型

    • Type ImplementationType: 实现的类型

    • ServiceLifetime Lifetime: 服务的生命周期

    • object ImplementationInstance: 实现服务的实例

    • Func<IServiceProvider, object> ImplementationFactory: 创建服务实例的工厂

注册

ServiceCollection提供了三种注册方法分别对应着三种实例生命周期。

  • AddSingleton 整个应用程序生命周期以内只创建一个实例

  • AddScoped 在同一个Scope内只初始化一个实例,可以理解为( 每一个request级别只创建一个实例,同一个http request会在一个 scope内)

  • AddTransient 每一次GetService都会创建一个新的实例

做一个简单测试:

创建测试类:

640?wx_fmt=png

在ConfigureServices里注册

640?wx_fmt=png

通过三种方法来获取这个Test类实例, Controller和View中代码如下

640?wx_fmt=png

运行,结果如下

03d437d6-2f18-452e-a7fd-ce62cea9038108b31487-b02b-4d62-bc2b-6d2026389f0c21a7fc13-6e7b-4590-910b-68d21a7a03d1

说明三种方式获取了三个不同的实例, 刷新一下页面, 又变成了另外三个不同的值.

现在在startup文件中将原来的 services.AddTransient<ITest,Test>() 改为 services.AddScoped<ITest,Test>() , 其他不变, 重新运行一下, 结果如下

050fef7e-2dc3-4d7d-8733-683b54b40b0b050fef7e-2dc3-4d7d-8733-683b54b40b0b050fef7e-2dc3-4d7d-8733-683b54b40b0b

刷新一下:

c9e5df8d-b085-4e3a-b883-fa083ba1d136
c9e5df8d-b085-4e3a-b883-fa083ba1d136
c9e5df8d-b085-4e3a-b883-fa083ba1d136

三组数字相同, 刷新一下, 又变成了另外三组一样的值, 这说明在同一次请求里, 获取的实例是同一个。

最常用的DBContext默认构建为Scope实例。即能减少实例初始化的消耗,还能实现跨Service事务的功能。

再将 services.AddScoped<ITest,Test>() 改为 services.AddSingleton<ITest,Test>() , 重新运行, 这次结果是

42ef5162-5781-427b-ac9d-a152500ed32f
42ef5162-5781-427b-ac9d-a152500ed32f
42ef5162-5781-427b-ac9d-a152500ed32f

发现三组值是一样的, 说明获得的是同一个实例, 在刷新一下页面, 仍然是这三组值, 说明多次请求获得的结果也是同一个实例.

640?wx_fmt=png

使用

  • 在Startup类ConfigureService中初始化

  • public void ConfigureServices(IServiceCollection services){services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);services.AddTransient<ITest, Test>();}

    方法中默认调用了services.AddMvc(), 是IServiceCollection的一个扩展方法 public static IMvcBuilder AddMvc(this IServiceCollection services), 作用就是向这个清单中添加了一些MVC需要的服务,例如Authorization、RazorViewEngin、DataAnnotations等。

  • Controller中使用

    private ITest _test;private ILogger<HomeController> _logger;public HomeController(ITest test, ILogger<HomeController> logger){    this._test = test;    this._logger = logger;
    }
  • 通过HttpContext来获取实例
    HttpContext下有一个RequestedService同样可以用来获取实例对象,不过这种方法一般不推荐。需要添加Microsoft.Extension.DependencyInjection的using来调用这个方法的。

    HttpContext.RequestServices.GetService<ITest>()
  • View中使用
    在View中通过@inject声明

    @inject ITest TestFromView<ul>
    <li>@TestFromView.Guid</li>
    </ul>

释放

对于每次请求, 我们最初配置的根IServiceProvider通过CreateScope()创建了一个新的IServiceScope, 而这个IServiceScope的ServiceProvider属性将负责本次该次请求的服务提供, 当请求结束, 这个ServiceProvider的dispose会被调用。

在2.0中, ServiceProvider只调用由它创建的 IDisposable 类型的 Dispose。 如果将一个实例添加到容器,它将不会被释放。
例如:

services.AddSingleton<ITest>(new Test()); 

替换为其它的 Ioc 容器

可以将默认的容器改为其他的容器, 比如Autofac, 需要把Startup类里面的 ConfigureService的 返回值从 void改为 IServiceProvider即可。而返回的则是一个AutofacServiceProvider。

640?wx_fmt=png

参考

  • Dependency injection in ASP.NET Core

  • 全面理解 ASP.NET Core 依赖注入

  • ASP.NET Core 2.0 : 六. 举个例子来聊聊它的依赖注入

  • ASP.NET Core中的依赖注入(1):控制反转(IoC)

  • ASP.NET Core 2.0使用Autofac实现IOC依赖注入竟然能如此的优雅简便

  • ASP.NET Core依赖注入最佳实践,提示&技巧

  • 把旧系统迁移到.Net Core 2.0 日记(2) - 依赖注入/日志NLog

  • ASP.NET Core依赖注入深入讨论

  • 在.NET Core中处理一个接口多个不同实现的依赖注入问题

  • ASP.NET Core 2.0 依赖注入

  • AspectCore中的IoC容器和依赖注入

  • ASP.NET Core依赖注入解读&使用Autofac替代实现

原文地址:https://www.cnblogs.com/royzshare/p/9440914.html


.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com

640?wx_fmt=jpeg

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/319788.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

P4357-[CQOI2016]K远点对【K-Dtree】

正题 题目链接:https://www.luogu.com.cn/problem/P4357 题目大意 平面上给出nnn个点&#xff0c;求第kkk远的点对距离。 解题思路 K-Dtree\text{K-Dtree}K-Dtree的模板题&#xff0c;但是这里只有二维&#xff0c;大概是每次根据一个维度把nnn个点分成两半像线段树一样丢到下…

【每日一题】7月7日题目精讲—最短路

来源&#xff1a;牛客网&#xff1a; 文章目录题目描述题解&#xff1a;代码&#xff1a;时间限制&#xff1a;C/C 1秒&#xff0c;其他语言2秒 空间限制&#xff1a;C/C 1048576K&#xff0c;其他语言2097152K 64bit IO Format: %lld题目描述 给一个连通图&#xff0c;每次询问…

【dfs】栅栏的木料(2012特长生 T4)

题目大意 给你n个木板&#xff0c;给你这些木板的长度&#xff0c;你可以把这些木板切开&#xff0c;现在有m个木料&#xff0c;问你最多可以切出多少个木料 解题思路 可以dfs枚举每个木料用哪个木板来切 但这样显然会超时&#xff0c;那么考虑剪枝 1.对于一些木板&#xf…

【c++算法刷题笔记】——洛谷1

2020/2/14-2/16 1. 循环提取一个数的每一位数字 while (d > 0) //d0跳出循环 {xd%10; //x每次为d的个位数 d d / 10; //相当于d每次舍去个位数 }2. cnew创建动态二维数组 int *anew int[n]; //创建动态一维数组 int(* a)[2…

【活动(广州)】office365的开发者训练营

Office 365每月有超过1亿的商业活跃用户&#xff0c;是现有最大的生产力服务。Office 365为开发人员提供了一个令人难以置信的机会&#xff0c;包括业务关键数据和数百万用户&#xff0c;以及一个旨在让人们保持工作流程的平台。作为一名开发人员&#xff0c;您可以使用每天使用…

P5325-[模板]Min_25筛

正题 题目链接:https://www.luogu.com.cn/problem/P5325 题目大意 定义一个积性函数满足f(pk)pk(pk−1)f(p^k)p^k(p^k-1)f(pk)pk(pk−1) 求∑i1nf(i)\sum_{i1}^nf(i)∑i1n​f(i) 解题思路 首先我们可以把f(pk)f(p^k)f(pk)是质数的情况拆成一个222阶的多项式f(x)x2−xf(x)x^2…

牛客网【每日一题】7月8日 Alliances

来源&#xff1a;牛客网 文章目录题目描述题解&#xff1a;代码&#xff1a;时间限制&#xff1a;C/C 5秒&#xff0c;其他语言10秒 空间限制&#xff1a;C/C 262144K&#xff0c;其他语言524288K 64bit IO Format: %lld题目描述 树国是一个有n个城市的国家&#xff0c;城市编号…

【bfs】廉价最短路径(2013特长生 T4)

题目大意 给你一个图&#xff0c;每条边有一个代价&#xff0c;让你求0到1在最短路径的前提下的最小代价 解题思路 bfs同时求个最代价 代码 #include<queue> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #de…

Ocelot简易教程(四)之请求聚合以及服务发现

上篇文章给大家讲解了Ocelot的一些特性并对路由进行了详细的介绍&#xff0c;今天呢就大家一起来学习下Ocelot的请求聚合以及服务发现功能。希望能对大家有所帮助。作者&#xff1a;依乐祝原文地址&#xff1a;https://www.cnblogs.com/yilezhu/p/9695639.html请求聚合Ocelot允…

邓公数据结构C++语言版学习笔记1

1. 对于计算幂2n2^n2n的算法优化 暴力算法时间复杂度O(n)O(n)O(n) __int64 power2BF_I(int n) //幂函数2^n算法&#xff08;蛮力迭代版&#xff09;&#xff0c;n > 0{ __int64 pow 1; //O(1)&#xff1a;累积器刜始化为2^0while (0 < n --) //O(n)&#xff1a;迭代n轮…

【每日一题】7月9日题目 Color

来源&#xff1a;牛客网&#xff1a; 时间限制&#xff1a;C/C 1秒&#xff0c;其他语言2秒 空间限制&#xff1a;C/C 131072K&#xff0c;其他语言262144K Special Judge, 64bit IO Format: %lld文章目录题目描述题解&#xff1a;代码&#xff1a;题目描述 给一个没有重边的二…

【DP】K星人的语言(2020特长生 T3)

题目大意 给你一个字符串和若干单词&#xff0c;问你最少删除多少字符使其成为若干单词连在一起的字符串 解题思路 设fif_ifi​为前i个位置的最小代价 然后枚举每个单词即可 代码 #include<cstdio> #include<cstring> #include<iostream> #include<al…

HttpClientFactory系列二:集成Polly处理瞬态故障

前言&#xff1a;最近&#xff0c;同事在工作中遇到了使用HttpClient,有些请求超时的问题&#xff0c;辅导员让我下去调研一下&#xff0c;HttpClinet的使用方式已经改成了之前博客中提到的方式&#xff0c;问题的原因我已经找到了&#xff0c;就是因为使用了伪异步&#xff0c…

Loj#6053-简单的函数【Min25筛】

正题 题目链接:https://loj.ac/p/6053 题目大意 定义一个积性函数f(pc)pxorcf(p^c)p\ xor\ cf(pc)p xor c&#xff0c;求∑i1nf(i)\sum_{i1}^nf(i)∑i1n​f(i) 解题思路 异或这个东西不太好搞&#xff0c;要考虑怎么求出ggg数组。 当ppp为质数时f(p)p−1f(p)p-1f(p)p−1&am…

邓公数据结构C++语言版学习笔记——二叉树

二叉树的遍历 一. preorder——先序遍历VLR 1. 递归先序遍历 2. 迭代先序遍历 3.先序遍历图解 二. inorder——先序遍历LVR 1. 递归中序遍历 2.迭代中序遍历 3.迭代中序遍历优化空间复杂度 <1>定义直接后继 <2>借用直接后继优化算法 解释&#xff1a;…

二分图匹配--匈牙利算法

文章目录二分图&#xff1a;匹配匈牙利算法代码&#xff1a;二分图&#xff1a; 二分图是一个无向图&#xff0c;点集分成子集X和Y&#xff0c;图中每一条边都是一边在X一边在Y 当且仅当无向图G的每一个回路次数都是偶数时&#xff08;包括0&#xff09;&#xff0c;G就是一个…

CF757F-Team Rocket Rises Again【最短路,DAG支配树】

正题 题目链接:https://www.luogu.com.cn/problem/CF757F 题目大意 nnn个点mmm条边的一张无向图&#xff0c;求删除sss以外的一个点改变sss到最多点的最短路。 解题思路 挺裸的一道题的&#xff0c;首先肯定要跑一遍最短路搞出最短路树。 然后如果最短路树上sss到某个点的路…

星座图(2020特长生 T4)

题目大意 给你一棵树&#xff0c;距离为2的两个点代价为wi∗wjw_i*w_jwi​∗wj​&#xff0c;问你最小代价和代价之和 解题思路 搜索这棵树&#xff0c;每次拿父亲和子节点一起计算即可 代码 #include<cstdio> #include<cstring> #include<algorithm> #de…

《Office 365开发入门指南》上市说明和读者服务

写在最开始的话拙作《Office 365开发入门指南》上周开始已经正式在各大书店、在线商城上市&#xff0c;欢迎对Office 365的开发、生态感兴趣的开发者、项目经理、产品经理参考本书&#xff0c;全面了解Office 365带来的全新机遇以及在具体业务应用开发中的场景。写作本书差不多…

简单理解手机快充

浅谈手机快充 背景 智能手机发展这么些年&#xff0c;屏幕显示越来越清晰&#xff0c;拍照像素越来越高&#xff0c;处理器性能越来越强&#xff0c;运行内存甚至开始超过PC&#xff0c;不过手机的续航还是一个问题&#xff1a;处理器性能以及一系列的增强无疑对电池是一个巨…