.NET 依赖注入和配置系统
文章目录
- 依赖注入
- DI几个概念
- .NET 中使用DI
- 生命周期
- IServiceProvider的服务定位器方法
- 配置系统
- Json文件配置
- 绑定类读取配置
依赖注入
依赖注入(Dependency Injection,DI)是控制反转(Inversion of Control,IOC)思想的实现方式。
控制反转的两种实现方式:
- 服务定位器(ServiceLocator);
- 依赖注入(Dependency Injection,DI);
DI几个概念
服务(service):对象;
注册服务;
服务容器:负责管理注册的服务;
查询服务:创建对象及关联对象;
对象生命周期:Transient(瞬态); Scoped(范围); Singleton(单例);
.NET 中使用DI
1、Install-Package Microsoft.Extensions.DependencyInjection
2、using Microsoft.Extensions.DependencyInjection
3、ServiceCollection用来构造容器对象IServiceProvider 。调用ServiceCollection的BuildServiceProvider()创建的ServiceProvider,可以用来获取BuildServiceProvider()之前ServiceCollection中的对象。
internal interface ITestService{public string Name { get; set; }public void SayHi();}internal class TestServiceImpl{public string Name { get; set; }public void SayHi(){Console.WriteLine($"Hi, I'm {Name}");}}internal class TestServiceImpl2
{public string Name { get; set; }public void SayHi(){Console.WriteLine($"你好,我是{Name}");}
}static void Main(string[] args){ServiceCollection services = new ServiceCollection();services.AddTransient<TestServiceImpl>();using (ServiceProvider sp = services.BuildServiceProvider()){TestServiceImpl testService = sp.GetRequiredService<TestServiceImpl>();testService.Name = "tom";testService.SayHi();}}
生命周期
Transient:
static void Main(string[] args)
{ServiceCollection services = new ServiceCollection();services.AddTransient<TestServiceImpl>();using (ServiceProvider sp = services.BuildServiceProvider()){var ts1 = sp.GetService<TestServiceImpl>();var ts2 = sp.GetService<TestServiceImpl>();Console.WriteLine(object.ReferenceEquals(ts1, ts2));}
}
输出:False
Singleton:
static void Main(string[] args)
{ServiceCollection services = new ServiceCollection();services.AddSingleton<TestServiceImpl>();using (ServiceProvider sp = services.BuildServiceProvider()){var ts1 = sp.GetService<TestServiceImpl>();var ts2 = sp.GetService<TestServiceImpl>();Console.WriteLine(object.ReferenceEquals(ts1, ts2));}
}
输出:True
Scoped:
static void Main(string[] args){ServiceCollection services = new ServiceCollection();services.AddScoped<TestServiceImpl>();using (ServiceProvider sp = services.BuildServiceProvider()){using (IServiceScope scope = sp.CreateScope()){var ts1 = scope.ServiceProvider.GetService<TestServiceImpl>();var ts2 = scope.ServiceProvider.GetService<TestServiceImpl>();Console.WriteLine(object.ReferenceEquals(ts1, ts2));}}}
输出:True
GetService和GetRequiredService有生命区别?
GetService如果找不到注入的类会返回null,
GetRequiredService如果找不到注入的类会抛出异常。
Tips: 生命周期的选择:如果类无状态,建议为Singleton;如果类有状态,且有Scope控制,建议为Scoped,因为通常这种Scope控制下的代码都是运行在同一个线程中的,没有并发修改的问题;在使用Transient的时候要谨慎。
IServiceProvider的服务定位器方法
T GetService<T>()如果获取不到对象,则返回null。object GetService(Type serviceType)T GetRequiredService<T>()如果获取不到对象,则抛异常object GetRequiredService(Type serviceType)IEnumerable<T> GetServices<T>()适用于可能有很多满足条件的服务IEnumerable<object> GetServices(Type serviceType)
总结:
1、依赖注入是有“传染性”的,如果一个类的对象是通过DI创建的,那么这个类的构造函数中声明的 所有服务类型的参数都会被DI赋值;但是如果一个对象是程序员手动创建的,那么 这个对象就和DI没有关系,它的构造函数中声明的服务类型参数就不会被自动赋值。
2、.NET的DI默认是 构造函数注入。
3、第三方DI容器:Autofac等。Autofac优点:支持属性注入、基于名字注入、基于约定的注入等。
配置系统
Json文件配置
1、创建一个json文件,文件名随意,比如config.json,设置“ 如果较新则复制”。
2、NuGet安装Microsoft.Extensions.Configuration和Microsoft.Extensions.Configuration.Json。
3、
config.json
{"exclude": ["**/bin","**/bower_components","**/jspm_packages","**/node_modules","**/obj","**/platforms"],"name": "yh","age": 18,"proxy": {"address": "bbaa","port": 80}
}
static void Main(string[] args){ConfigurationBuilder configBuilder = new ConfigurationBuilder();configBuilder.AddJsonFile(
"config.json", optional: false, reloadOnChange: false);IConfigurationRoot config = configBuilder.Build();string name = config["name"];string proxyAddress = config.GetSection("proxy:address").Value;Console.WriteLine(name);Console.WriteLine(proxyAddress);}
optional参数:表示这个文件是否可选。初学时,建议optional设置为false,这样写错了的话能够及时发现。
reloadOnChange参数:表示如果文件修改了,是否重新加载配置。
绑定类读取配置
绑定一个类,自动完成配置的读取。
1、NuGet安装:Microsoft.Extensions.Configuration.Binder
2、
static void Main(string[] args)
{ConfigurationBuilder configBuilder = new ConfigurationBuilder();configBuilder.AddJsonFile(
"config.json", optional: false, reloadOnChange: false);IConfigurationRoot configRoot = configBuilder.Build();Proxy proxy = configRoot.GetSection("proxy").Get<Proxy>();Console.WriteLine(proxy.Address);Console.WriteLine(proxy.Port);Config config = configRoot.Get<Config>();Console.WriteLine(config.Name);Console.WriteLine(config.Proxy.Address);
}class Config{public string Name { get; set; }public int Age { get; set; }public Proxy Proxy { get; set; }}class Proxy{public string Address { get; set; }public int Port { get; set; }}
相关文章:
.NET 依赖注入和配置系统
文章目录 依赖注入DI几个概念.NET 中使用DI生命周期IServiceProvider的服务定位器方法 配置系统Json文件配置绑定类读取配置 依赖注入 依赖注入(Dependency Injection,DI)是控制反转(Inversion of Control,IOC…...
什么是”法兰“?
“法兰”,第一次听说这个词,怪怪的,后来就知道了和“鲁棒”是一类人才发明的词; 所以就知道这个词原本是“flange”; 那这样就好解释了, 【 使物体更加坚固或(如火车车轮)保持正确…...
Vulnhub靶机:HackLAB_Vulnix
一、介绍 运行环境:Virtualbox(攻击机)和VMware(靶机) 攻击机:kali(192.168.56.101) 靶机:HackLAB: Vulnix(192.168.56.110) 目标:获取靶机root权限和flag 靶机下载地址&#x…...
软件推荐 篇三十七:开源免费无广告的在线音乐免费播放 | MusicFree纯净无广告体验-小众冷门推荐
引言 自从QQ音乐没了杰伦、某云开始收费,除了各种广告弹窗导致电脑卡的要死,打工人就靠这点音乐背景熬夜了,木有办法,得有个开源免费的听歌软件吧,一搜github,软件一大堆,作为一个打工仔&#…...
Hive SQL必刷练习题:留存率问题(*****)
留存率: 首次登录算作当天新增,第二天也登录了算作一日留存。可以理解为,在10月1号登陆了。在10月2号也登陆了,那这个人就可以算是在1号留存 今日留存率 (今日登录且明天也登录的用户数) / 今日登录的总…...
在Linux/Ubuntu/Debian中创建自己的命令快捷方式
虽然图标快捷方式使你移动鼠标双击就打开目标,但是你还是需要先定位到它。而在终端Terminal中你只需要输入一个自定义命令就能一步到位。 要在 Ubuntu 中创建你自己的命令或别名,你可以使用主目录中的“.bashrc”文件。 以下是创建通过 Wine 运行 Photo…...
vue学习笔记——Vue3循环生成表单时,对每一行新生成的数据添加表单验证的方法
应用场景: 在form表单内,动态生成一个数组类型的一组数据,要求对生成的每一组数据内容进行表单验证。例如动态添加人员,并对每个人的人员的信息输入框进行表单验证。 解决思路: 把rules的验证规则循环写在element ui的…...
用C++做一个植物大战僵尸
制作一个完整的“植物大战僵尸”游戏是一个非常大的项目,涉及图形渲染、碰撞检测、用户输入处理、音效、动画、游戏逻辑等多个方面。由于这个话题非常广泛,我可以提供一个简化的版本或者一个框架来启动你的项目。 以下是一个简化的框架,帮助…...
政安晨:【深度学习实践】【使用 TensorFlow 和 Keras 为结构化数据构建和训练神经网络】(三)—— 随机梯度下降
政安晨的个人主页:政安晨 欢迎 👍点赞✍评论⭐收藏 收录专栏: TensorFlow与Keras实战演绎 希望政安晨的博客能够对您有所裨益,如有不足之处,欢迎在评论区提出指正! 这篇文章中,咱们将使用Keras和TensorFlow…...
普通用户无法连接到docker服务
环境 tt:~$ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 22.04.3 LTS Release: 22.04 Codename: jammy问题 tt:~$ sudo apt install docker.io -ytt:~$ docker info Client:Version: 24.0.5Context: d…...
Rancher(v2.6.3)——Rancher部署Nginx(单机版)
Rancher部署Nginx详细说明文档:https://gitee.com/WilliamWangmy/snail-knowledge/blob/master/Rancher/Rancher%E4%BD%BF%E7%94%A8%E6%96%87%E6%A1%A3.md#5rancher%E9%83%A8%E7%BD%B2nacos ps:如果觉得作者写的还行,能够满足您的需求&#x…...
java问题解释
问题1:请解释Java中的异常处理机制,并讨论其在软件开发中的重要性。 回答: Java中的异常处理机制是一种强制性的错误处理机制,它允许程序在运行时检测到异常情况,并采取适当的措施进行处理。异常是在程序执行过程中发…...
TSN协议原理!看完这一篇就够了(1)——时钟同步IEEE802.1AS-2020
▎前言 在许多应用场景中,一个本地局域网中互联的设备集群需要共享同一个时间,以支持各设备的协同工作。例如:音频设备与视频设备的配合播放,雷达与摄像头的数据融合等;这样一个看似简单的域功能,细化成为…...
Intel被喷惨的大小核CPU终于有救,12、13代也沾了光
2021年 Intel 将混合架构引入 PC ,至今也没能让所有用户接受这一改动。 虽然 PE 核心设计 帮助我们更好理解鸡兔同笼问题 带来了额外的多线程性能提升,但对于游戏玩家们可就不那么友好了。 关了吧觉得亏,不关吧又要时不时担心大核偷懒、小核…...
JAVA入门第一步
学习总结: 打开CMD常见的CMD命令 一、打开CMD CMD的概念 CMD是Windows操作系统中的命令提示符(Command Prompt)程序,它是一种命令行工具,可以让用户通过键入命令来与计算机进行交互。CMD是Windows中一个基本的系统组件,它提供了一…...
【scala】使用gradle和scala构建springboot程序
零、版本说明: springboot: 2.7.18 使用log4j2,不使用springboot自带的logback scala版本:2.11 jackson版本:2.16.0 一、依赖: buildscript {dependencies {// using spring-boot-maven-plugin as package toolclasspath("…...
Linux sfdisk命令教程:硬盘分区表编辑器(附实例详解和注意事项)
Linux sfdisk命令介绍 sfdisk是一个用于编辑硬盘分区表的命令。它与fdisk和cfdisk类似,但具有更多的功能。此外,与这两个程序不同,sfdisk可以非交互式地运行。它通常用于从脚本中对驱动器进行分区,或用于分区表的备份和恢复。 L…...
Godot 学习笔记(5):彻底的项目工程化,解决GodotProjectDir is null+工程化范例
文章目录 前言GodotProjectDir is null解决方法解决警告问题根本解决代码问题测试引用其实其它库的输出路径无所谓。 工程化范例环境命名规范Nuget项目结构架构代码ISceneModelIOC服务 测试GD_Extension 通用扩展TestUtils GD_ProgramTestServiceMainSceneModel Godot对应的脚本…...
算法打卡day23|回溯法篇03|Leetcode 39. 组合总和、40.组合总和II、131.分割回文串
算法题 Leetcode 39. 组合总和 题目链接:39. 组合总和 大佬视频讲解:组合总和视频讲解 个人思路 这道组合题主要是有总和的限制,当递归和超过了总和就return,递归时加上回溯去遍历数组。 解法 回溯法 把组合问题抽象为如下树形结构 如上…...
Google研究者们提出了VLOGGER模型
每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…...
C++ STL 容器选型实战:vector/list/map/unordered_map 性能对比与选型指南
一、前言:为什么容器选型是 C 工程的核心?在 C 后端开发、Qt 桌面应用、高性能服务器、嵌入式系统、游戏引擎、实时仿真、数据分析等几乎所有工业级项目中,STL 容器的选型直接决定程序性能、内存占用、可维护性与稳定性。很多开发者习惯随手写…...
Worldwide, Apr 2026 : PYPL 全球编程语言流行度排行榜火热出炉
根据本期榜单数据,以下是对各编程语言流行度和趋势的分析: 总体趋势:Python 继续稳居榜首,其流行度份额为 36.21%,并且增长了 5.7%。这一增长表明Python在数据科学、人工智能和Web开发等领域的应用继续受到广泛关注。C…...
DAMOYOLO-S数据库联动应用:检测结果自动化存储与查询
DAMOYOLO-S数据库联动应用:检测结果自动化存储与查询 你有没有遇到过这样的场景?一个智能安防摄像头,每天24小时不间断地运行,DAMOYOLO-S模型在里面兢兢业业地识别着每一个经过的人和车。但问题是,这些宝贵的检测结果…...
24小时无人值守:OpenClaw+Phi-3-vision-128k-instruct自动化监控系统
24小时无人值守:OpenClawPhi-3-vision-128k-instruct自动化监控系统 1. 为什么需要自动化监控系统 去年我负责一个内部数据看板项目时,经常遇到凌晨突发故障却无人值守的情况。直到第二天上班才发现问题,损失了宝贵的响应时间。传统监控工具…...
OpenClaw调试技巧:解决SecGPT-14B模型返回结果异常问题
OpenClaw调试技巧:解决SecGPT-14B模型返回结果异常问题 1. 问题背景与现象描述 上周在尝试用OpenClaw对接SecGPT-14B模型时,遇到了一个棘手的问题:模型返回的结果经常出现截断或格式混乱。具体表现为: 当请求生成网络安全报告时…...
Graphormer效果实测:100个DrugBank分子logP预测MAE=0.28(SOTA水平)
Graphormer效果实测:100个DrugBank分子logP预测MAE0.28(SOTA水平) 1. 模型介绍 Graphormer是一种基于纯Transformer架构的图神经网络,专门为分子图(原子-键结构)的全局结构建模与属性预测而设计。该模型在…...
Android Studio课程设计实战:从零构建一个多功能备忘录记事本
1. 项目背景与开发环境搭建 第一次用Android Studio做课程设计时,我盯着空白的项目界面发呆了半小时——明明老师演示时行云流水,自己动手却连开发环境都配不齐。这个多功能备忘录项目就是从这种困境中摸索出来的实战经验,特别适合刚接触Andr…...
Qwen3.5-9B快速上手:3步启动WebUI(supervisorctl restart)超详细步骤
Qwen3.5-9B快速上手:3步启动WebUI(supervisorctl restart)超详细步骤 1. 开篇介绍 Qwen3.5-9B是一款拥有90亿参数的开源大语言模型,具备强大的逻辑推理、代码生成和多轮对话能力。特别值得一提的是,它的多模态变体Qw…...
大数据可视化
1. 传播分析评估维度:包含认知(知晓、记忆)、行动(点击、搜索)、情感(喜好、美誉)三个层面传统评估:主要关注广告点击率和观看次数等表面指标深度评估:需要分析广告观看后…...
基于TuGraph的医疗知识图谱构建与智能问答实践
1. 医疗知识图谱构建全流程解析 医疗知识图谱作为医疗信息化的重要基础设施,正在深刻改变着医疗数据的组织方式和应用模式。不同于传统的关系型数据库,图数据库能够更直观地展现疾病、症状、药物等实体间的复杂关系。我们以TuGraph图数据库为例ÿ…...
