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

.NET 依赖注入和配置系统

文章目录

    • 依赖注入
      • DI几个概念
      • .NET 中使用DI
      • 生命周期
      • IServiceProvider的服务定位器方法
    • 配置系统
      • Json文件配置
      • 绑定类读取配置

依赖注入

依赖注入(Dependency Injection,DI)是控制反转(Inversion of Control,IOC)思想的实现方式。

控制反转的两种实现方式:

  1. 服务定位器(ServiceLocator);
  2. 依赖注入(Dependency Injection,DI);

DI几个概念

服务(service):对象;
注册服务;
服务容器:负责管理注册的服务;
查询服务:创建对象及关联对象;
对象生命周期:Transient(瞬态); Scoped(范围); Singleton(单例);

.NET 中使用DI

1、Install-Package Microsoft.Extensions.DependencyInjection
2、using Microsoft.Extensions.DependencyInjection
3、ServiceCollection用来构造容器对象IServiceProvider 。调用ServiceCollectionBuildServiceProvider()创建的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

GetServiceGetRequiredService有生命区别?
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.ConfigurationMicrosoft.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; }}

相关文章:

  • WebGL 理论基础 01 WebGL 基础概念
  • Linux常用命令(二)
  • Qt 容器类控件
  • 在Linux/Ubuntu/Debian中创建自己的命令快捷方式
  • Vue3快速上手(十七)Vue3之状态管理Pinia
  • 基于sortablejs实现拖拽element-ui el-table表格行进行排序
  • java Flink(四十二)Flink的序列化以及TypeInformation介绍(源码分析)
  • 探索ChatGPT时代下的下一代信息检索系统:机遇与挑战
  • 系统资源耗尽对服务器的影响
  • Linux 系统日志
  • (一)Linux+Windows下安装ffmpeg
  • docker opensearch arm64 运行失败解决方案
  • 国内ip切换是否合规?
  • 针对ETC系统的OBE-SAM模块设计方案
  • python --- 练习题3
  • 30天自制操作系统-2
  • android高仿小视频、应用锁、3种存储库、QQ小红点动画、仿支付宝图表等源码...
  • Docker下部署自己的LNMP工作环境
  • ES6, React, Redux, Webpack写的一个爬 GitHub 的网页
  • Java到底能干嘛?
  • JDK9: 集成 Jshell 和 Maven 项目.
  • jquery ajax学习笔记
  • Netty 4.1 源代码学习:线程模型
  • Next.js之基础概念(二)
  • VUE es6技巧写法(持续更新中~~~)
  • VuePress 静态网站生成
  • 第13期 DApp 榜单 :来,吃我这波安利
  • 工作中总结前端开发流程--vue项目
  • 和 || 运算
  • 力扣(LeetCode)965
  • 使用Gradle第一次构建Java程序
  • 物联网链路协议
  • 小程序 setData 学问多
  • 小李飞刀:SQL题目刷起来!
  • 怎么把视频里的音乐提取出来
  • 微龛半导体获数千万Pre-A轮融资,投资方为国中创投 ...
  • # include “ “ 和 # include < >两者的区别
  • ### Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLTr
  • #define、const、typedef的差别
  • #数学建模# 线性规划问题的Matlab求解
  • #中的引用型是什么意识_Java中四种引用有什么区别以及应用场景
  • (007)XHTML文档之标题——h1~h6
  • (6)设计一个TimeMap
  • (C语言)深入理解指针2之野指针与传值与传址与assert断言
  • (zt)基于Facebook和Flash平台的应用架构解析
  • (附源码)springboot 个人网页的网站 毕业设计031623
  • (附源码)springboot家庭财务分析系统 毕业设计641323
  • (附源码)计算机毕业设计ssm基于B_S的汽车售后服务管理系统
  • (离散数学)逻辑连接词
  • (转载)PyTorch代码规范最佳实践和样式指南
  • (转载)跟我一起学习VIM - The Life Changing Editor
  • .NET CF命令行调试器MDbg入门(一)
  • .NET Core SkiaSharp 替代 System.Drawing.Common 的一些用法
  • .net MySql
  • .Net 应用中使用dot trace进行性能诊断