当前位置: 首页 > news >正文

ASP.NET Core - 依赖注入(二)

2,NET Core 依赖注入的基本用法

话接上篇,这一章介绍 .NET Core 框架自带的轻量级 Ioc 容器下服务使用的一些知识点,大家可以先看看上一篇文章 [ASP.NET Core - 依赖注入(一)]

2.3 服务解析

通过 IServiceCollection 注册了服务之后,可以通过以下方式解析相应服务的实例:

  • IServiceProvider
    IServiceProiver 实例由 IServiceCollection 通过 BuildServiceProvider() 方法创建,在 ASP.NET Core 中,主机启动的时候会创建一个全局的 IServiceProvider,并且此实例也在容器当中。所有在容器注册过的服务都可以通过 IServiceProiver 进行解析,当然该服务的依赖项必须也在容器中注册。
  • ActivatorUtilities
    用于手动创建未在DI容器中注册的服务实例

2.3.1 服务注入方式

当我们通过容器解析一个服务实例的时候,容器根据当前服务的链式依赖关系图解析其依赖项,根据依赖项的生命周期或创建、或从已有的实例获取,然后注入到我们解析的服务当中。在一个服务中获取另一个服务实例的方式由以下几种:

(1) 构造函数注入

构造函数注入是非常常见的服务注入方式,也是微软最推荐的方式,这种方式可以明确地声明当前类所依赖的东西,一目了然。如同上面的示例代码中,使用的就是构造函数注入方式。构造函数注入,对于类的构造函数有以下要求:

  • 构造函数可以接收非依赖注入的参数,但必须提供默认值

  • 当服务通过 IServiceProvider 解析时,要求构造函数必须是 public

    当服务由 ActivatorUtilities 解析时,构造函数注入要求只存在一个适用的构造函数。 支持构造函数重载,但其参数可以全部通过依赖注入来实现的重载只能存在一个。

  • 如果发现构造函数时存在歧义,将引发异常,例如以下情况:

public class ExampleService
{public ExampleService(){}public ExampleService(ILogger<ExampleService> logger){// omitted for brevity}public ExampleService(IOptions<ExampleOptions> options){// omitted for brevity}
}

 

(2) 属性注入

这里有一点需要说明,.NET Core 内置的依赖注入框架并不支持属性注入,如果需要使用属性注入需要结合第三方依赖注入框架进行使用,如autofac。

顾名思义,属性注入就是通过类中的属性注入需要的服务,要求属性必须是 public ,并且具备 get、set 访问器。如下:

 

 

属性注入一般用于注入一些即使缺失了也不会导致当前类无法工作的依赖项,如日志记录等。这种时候会为数据注入设置一个默认实现,防止该属性为空,导致当前类的功能受影响。

(3) 方法注入

通过 FromServicesAttribute 特性在控制器的方法参数中注入,这种方式只能用于控制器。默认情况下,控制器示例由容器来管理,在入口文件调用 builder.Services.AddControllers(); 时注册到容器中。

[HttpGet(nameof(InjectTest3))]
public Task InjectTest3([FromServices] IRabbit rabbit)
{Console.WriteLine(rabbit is Rabbit);return Task.CompletedTask;
}

 

这种方式用于缩小依赖注入的粒度,适用于注入的服务只在当前方法使用的时候,是对构造函数注入的简化。

(4) 手动解析

在.NET框架中,任何可以拿得到 IServiceProvider 实例的地方都可以通过 GetRequiredService() 或者 GetService() 解析我们需要的服务。直接使用 IServiceProvider 是服务定位器模式的一个示例。这通常被认为是反模式,因为它隐藏了类的依赖关系。这种方式在某些情况下是有用的,但是应该尽量避免。

 

 GetService() 与 GetRequiredService() 的区别在于解析服务时,如果该服务没有在容器中注册,前者会返回Null,而后者会抛出异常。

除了通过注入 IServiceProvider 来解析服务之外,其他的方式,例如 HttpContext 中也包含 IServiceProvider 实例,如: 

var rabbit1 = HttpContext.RequestServices.GetRequiredService<IRabbit>();

 

2.3.2 ActivatorUtilities 使用

通过 ActivatorUtilities 解析服务比较简单,常用的由以下两个方法:

ActivatorUtilities.CreateInstance<HelloService>(provider, "test");
ActivatorUtilities.GetServiceOrCreateInstance<IHelloService>(provider);

 其中 CreateInstance 方法的泛型类型需要是具体的类型,而不是接口,这个方法还可以传入构造函数需要的,但没有在容器中注册的参数。GetServiceOrCreateInstance 方法会先尝试从容器获取实例,获取不到再创建,不支持不在容器中注册的构造函数参数。

相关文章:

ASP.NET Core - 依赖注入(二)

2&#xff0c;NET Core 依赖注入的基本用法 话接上篇&#xff0c;这一章介绍 .NET Core 框架自带的轻量级 Ioc 容器下服务使用的一些知识点&#xff0c;大家可以先看看上一篇文章 [ASP.NET Core - 依赖注入(一)] 2.3 服务解析 通过 IServiceCollection 注册了服务之后&#xf…...

Scala之集合(1)

目录 ​​​​​​​集合介绍&#xff1a; 不可变集合继承图&#xff1a;​编辑 可变集合继承图 数组&#xff1a; 不可变数组&#xff1a; 样例代码&#xff1a; 遍历集合的方法&#xff1a; 1.for循环 2.迭代器 3.转换成List列表&#xff1a; 4.使用foreach()函数&a…...

公网使用SSH远程登录macOS服务器【内网穿透】

文章目录前言1. macOS打开远程登录2. 局域网内测试ssh远程3. 公网ssh远程连接macOS3.1 macOS安装配置cpolar3.2 获取ssh隧道公网地址3.3 测试公网ssh远程连接macOS4. 配置公网固定TCP地址4.1 保留一个固定TCP端口地址4.2 配置固定TCP端口地址5. 使用固定TCP端口地址ssh远程前言…...

PVE相关的各种一键脚本(一键安装PVE)(一键开设KVM虚拟化的NAT服务器-自带内外网端口转发)

PVE 原始仓库&#xff1a;https://github.com/spiritLHLS/pve 前言 建议debian在使用前尽量使用最新的系统 非debian11可使用 debian一键升级 来升级系统 当然不使用最新的debian系统也没问题&#xff0c;只不过得不到官方支持 请确保使用前机器可以重装系统&#xff0c;…...

CSDN目录博客(zhaoshuangjian)

总目录 一、Java1.1 高并发1.2 多线程1.3 集合1.4 I/O1.5 异常1.6 事务1.7 锁机制1.8 JVM 二、数据库2.1 mysql2.1.1 mysql索引2.1.1 mysql锁2.1.1 mysql事务2.1.1 2.2 oracle2.3 postgresql2.4 达梦2.5 人大金仓kingbase 三、设计模式四、中间件4.1 缓存中间件-redis4.2 缓存中…...

uniapp人脸识别解决方案

APP端&#xff1a; 因为APP端无法使用uni的camera组件&#xff0c;最开始考虑使用内嵌webview的方式&#xff0c;通过原生dom调用video渲染画面然后通过canvas截图。但是此方案兼容性在ios几乎为0&#xff0c;如果app只考虑安卓端的话可以采用此方案。后面又想用live-pusher组件…...

hashlib模块

欢迎关注博主 Mindtechnist 或加入【Linux C/C/Python社区】一起探讨和分享Linux C/C/Python/Shell编程、机器人技术、机器学习、机器视觉、嵌入式AI相关领域的知识和技术。 hashlib模块专栏&#xff1a;《python从入门到实战》 哈希算法&#xff0c;也叫摘要算法。 加密&…...

NC65合并报表如何取消上报并退回以及注意事项和相关问题总结

NC65合并报表如何取消上报并退回&#xff1f; 在【企业绩效管理】-【合并报表】-【合并】-【合并执行】节点中&#xff0c;点击〖数据中心〗按钮&#xff0c;在弹出的〖合并报表数据中心〗界面中&#xff0c;点击〖报送管理〗-〖合并方案请求退回〗&#xff0c;然后到【合并综…...

28岁,终于从字节退休了...

大厂一直是每个程序员都向往职业目标&#xff0c;大厂意味着薪资高、福利好、倍有面儿&#xff0c;而且发展空间也大。甚至有人调侃不想进大厂的程序员不是好程序员。 而在网上&#xff0c;也有各个网友分享自己在大厂的经历&#xff0c;在某平台还有一个近2600万浏览的话题&a…...

数据的表示和存储——

目录 浮点数的编码表示 浮点数类型 ​编辑 浮点数的表示 &#xff08;1&#xff09;浮点数&#xff08;Float Point&#xff09;的表示范围 &#xff08;2&#xff09;规格化数形式 &#xff08;3&#xff09;IEEE 754标准 其他形式的机器数表示 个人总结 浮点数的编码表…...

springboot零基础到项目实战

推荐教程&#xff1a; springboot零基础到项目实战 SpringBoot这门技术课程所包含的技术点其实并不是很多&#xff0c;但是围绕着SpringBoot的周边知识&#xff0c;也就是SpringBoot整合其他技术&#xff0c;这样的知识量很大&#xff0c;例如SpringBoot整合MyBatis等等。因此…...

自媒体都在用的5个素材网站,视频、音效、图片全部免费下载~

推荐几个自媒体必备的素材库&#xff0c;免费可商用&#xff0c;建议收藏&#xff01; 1、菜鸟图库 视频素材下载_mp4视频大全 - 菜鸟图库 国内超大的素材库&#xff0c;在这里你可以找到设计、办公、图片、视频、音频等各种素材。视频素材就有上千个&#xff0c;全部都很高清…...

开放式耳机新巅峰!南卡OE Pro兼备澎湃音质、舒适佩戴、创新设计

众所周知&#xff0c;当初苹果带来TWS耳机新时代以后&#xff0c;后面有许多的蓝牙耳机相继跟随和模仿&#xff0c;但NANK南卡却独辟蹊径&#xff0c;将在近日重磅推出首款0压无感全开放无线耳机——南卡OE Pro&#xff0c;走向开放式TWS耳机的新时代。 31度黄金倾斜受力面&…...

1700页,卷S人的 Java《八股文》PDF手册,涨薪跳槽拿高薪就靠它了

大家好&#xff0c;最近有不少小伙伴在后台留言&#xff0c;又得准备面试了&#xff0c;不知道从何下手&#xff01; 不论是跳槽涨薪&#xff0c;还是学习提升&#xff01;先给自己定一个小目标&#xff0c;然后再朝着目标去努力就完事儿了&#xff01; 为了帮大家节约时间&a…...

普通人是否能从ChatGPT中分一杯羹?

ChatGPT3.0刚刚推出&#xff0c;最开始的时候&#xff0c;人们只是将ChatGPT看作一个很会聊天的机器人&#xff0c;无论问题多么天马行空&#xff0c;它的答案看上去都有理有据。后来&#xff0c;像打开潘多拉魔盒一样&#xff0c;很多人开始拿它编大纲、撰写文案、编代码、创作…...

SpringBoot自动装配原理(附面试快速答法)

文章目录SpringBoot自动装配原理1. 从调用SpringApplication构造器方法开始2. 解析启动类4.按需装配4.1 分析dubbo自动装配5. 如果定义自己的starter6. 面试答法SpringBoot自动装配原理 之前面试被问到这个题目&#xff0c;只会答一些spi、AutoConfigration注解、Import之类的&…...

如何在大厂做好架构演进?

1 架构演进的定义 1.1 定义 通过设计新的系统架构(4R)&#xff0c;来应对业务和技术的发展变化。 1.2 关键点 新架构新的复杂度 1.3 目的 应对业务和技术的发展变化后带来新的复杂度。 案例 淘宝去IOE&#xff0c;是因为业务发展大了后&#xff0c;IOE的成本和可控性难…...

减半技术实现求a的n次幂

目录 减半技术实现求a的n次幂 程序设计 程序分析 减半技术实现求a的n次幂 【问题描述】给定两个正整数a和n,采用减半技术求a的n次幂;其中a<100,b<20; 【输入形式】两个整数a,n(a与n中间用空格隔开); 【输出形式】一个整数 【样例输入1】2 3 【样例输出1】8 【样…...

MYSQL8窗口函数

MYSQL8窗口函数 MYSQL8窗口函数窗口函数分类序号函数--排行榜row_number()示例rank()示例dense_rank()示例partition by对每个分区内的行进行排名不加partition by全局排序 开窗聚合函数分布函数CUME_DIST()PERCENT_RANK() 前后函数LAG()的用法LEAD() 头尾函数其他函数NTH_VALU…...

全国大学生智能汽车竞赛——安装Ubuntu操作系统(双系统)

1.1 电脑分区 1.1.1 分区原因 由于我们想要在电脑上同时安装Windows和Ubuntu系统&#xff0c;所以就要在window使用的内存中划分出来一段用来给Ubuntu系统使用&#xff0c;相当于一个应用程序一样 1.1.2 分区步骤 1.右击此电脑&#xff0c;点击管理&#xff0c;然后双击左侧…...

HTML 语义化

目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案&#xff1a; 语义化标签&#xff1a; <header>&#xff1a;页头<nav>&#xff1a;导航<main>&#xff1a;主要内容<article>&#x…...

Vue记事本应用实现教程

文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展&#xff1a;显示创建时间8. 功能扩展&#xff1a;记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...

微信小程序之bind和catch

这两个呢&#xff0c;都是绑定事件用的&#xff0c;具体使用有些小区别。 官方文档&#xff1a; 事件冒泡处理不同 bind&#xff1a;绑定的事件会向上冒泡&#xff0c;即触发当前组件的事件后&#xff0c;还会继续触发父组件的相同事件。例如&#xff0c;有一个子视图绑定了b…...

Nginx server_name 配置说明

Nginx 是一个高性能的反向代理和负载均衡服务器&#xff0c;其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机&#xff08;Virtual Host&#xff09;。 1. 简介 Nginx 使用 server_name 指令来确定…...

相机从app启动流程

一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...

多种风格导航菜单 HTML 实现(附源码)

下面我将为您展示 6 种不同风格的导航菜单实现&#xff0c;每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...

用docker来安装部署freeswitch记录

今天刚才测试一个callcenter的项目&#xff0c;所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...

实现弹窗随键盘上移居中

实现弹窗随键盘上移的核心思路 在Android中&#xff0c;可以通过监听键盘的显示和隐藏事件&#xff0c;动态调整弹窗的位置。关键点在于获取键盘高度&#xff0c;并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...

什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南

文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/55aefaea8a9f477e86d065227851fe3d.pn…...

在WSL2的Ubuntu镜像中安装Docker

Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包&#xff1a; for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...