【无标题】.Net6开发winform程序使用依赖注入学习通http://www.bdgxy.com/
文章来源: 学习通http://www.bdgxy.com/
普学网http://www.boxinghulanban.cn/
智学网http://www.jaxp.net/
表格制作excel教程http://www.tpyjn.cn/
学习通http://www.tsgmyy.cn/
.net? Blazor webassembly 和 webAPI 内建支持依赖注入, Winform 和 Console 应用虽然不带有依赖注入功能, 但增加依赖注入也很简单.?
本文将示例如何为 WinForm 程序增加依赖注入特性, 实现通过DI容器获取Cofiguration 实例, 并读取appsettings.json文件.
安装依赖库, 有点多
- Microsoft.Extensions.DependencyInjection 库, 依赖注入的类库
- Microsoft.Extensions.Configuration 库, 包含IConfiguration接口 和 Configuration类
- Microsoft.Extensions.Configuration.Json 库, 为 IConfiguration 增加了读取 Json 文件功能,
- Microsoft.Extensions.Hosting 库,? 提供 Host 静态类,? 有能力从 appsettings.{env.EnvironmentName}.json 加载相应 env? 的设定值,? 并将设定值用于IConfiguration/ILoggerFactory中, 同时增加 Console/EventSourceLogger 等 logger.
仅适用于 Asp.Net core 和 Console 类应用
- Microsoft.Extensions.Logging 库,? 包含 ILogger 和 ILoggerFactory 接口
- Serilog.Extensions.Logging 库, 为DI 容器提供 AddSerilog() 方法.
- Serilog.Sinks.File 库, 提供 Serilog rolling logger
- Serilog.Sinks.Console 库, 增加 serilog console logger
- Serilog.Settings.Configuration 库, 允许在 appsetting.json? 配置 Serilog, 顶层节点要求是 Serilog.?
- Serilog.Enrichers.Thread 和 Serilog.Enrichers.Environment 库,? 为输出日志文本增加 Thread和 env 信息
补充库:
- Microsoft.Extensions.Options.ConfigurationExtensions 库,? 为DI容器增加了从配置文件中实例化对象的能力, 即? serviceCollection.Configure<TOptions>(IConfiguration)
- Microsoft.Extensions.Options 库,? 提供以强类型的方式读取configuration文件, 这是.Net中首选的读取configuration文件方式.
appsettings.json 配置文件
配置一个 ConnectionString, 另外配 serilog
{
“ConnectionStrings”: {
“oeeDb”: “Server=localhost\SQLEXPRESS01;Database=Oee;Trusted_Connection=True;”
},
“Serilog”: {
“Using”: [ “Serilog.Sinks.Console”, “Serilog.Sinks.File” ],
“MinimumLevel”: “Debug”,
“WriteTo”: [
{ “Name”: “Console” },
{
“Name”: “File”,
“Args”: { “path”: “Logs/serilog.txt” }
}
],
“Enrich”: [ “FromLogContext”, “WithMachineName”, “WithThreadId” ]
}
}
Program.cs , 增加DI容器
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Serilog;
namespace Collector
{
internal static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
ApplicationConfiguration.Initialize();
//未使用依赖注入的写法
//Application.Run(new FormMain());
//生成 DI 容器ServiceCollection services = new ServiceCollection();ConfigureServices(services); //注册各种服务类//先用DI容器生成 serviceProvider, 然后通过 serviceProvider 获取Main Form的注册实例var serviceProvider =services.BuildServiceProvider();var formMain = serviceProvider.GetRequiredService<FormMain>(); //主动从容器中获取FormMain实例, 这是简洁写法// var formMain = (FormMain)serviceProvider.GetService(typeof(FormMain)); //更繁琐的写法Application.Run(formMain); }/// <summary>/// 在DI容器中注册所有的服务类型 /// </summary>/// <param name="services"></param>private static void ConfigureServices(ServiceCollection services){//注册 FormMain 类services.AddScoped<FormMain>();//register configurationIConfigurationBuilder cfgBuilder = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("appsettings.json").AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT")}.json", optional: true, reloadOnChange: false);IConfiguration configuration=cfgBuilder.Build();services.AddSingleton<IConfiguration>(configuration);//Create logger instancevar serilogLogger = new LoggerConfiguration().ReadFrom.Configuration(configuration).Enrich.FromLogContext().CreateLogger();//register loggerservices.AddLogging(builder => {object p = builder.AddSerilog(logger: serilogLogger, dispose: true);});}
}
}
FormMain.cs , 验证依赖注入的效果
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
namespace Collector
{
public partial class FormMain : Form
{
private readonly IConfiguration _configuration;
private readonly ILogger _logger;
/// <summary>/// 为 FormMain 构造子增加两个形参, 构造子参数将由于DI容器自动注入/// </summary>/// <param name="configuration"></param>/// <param name="logger">形参必须是 ILogger泛型类型, 不能是 ILogger 类型</param>public FormMain(IConfiguration configuration, ILogger<FormMain> logger) {_configuration = configuration;_logger = logger;InitializeComponent();var connectionString = _configuration.GetConnectionString("oeeDb"); //从配置文件中读取oeeDb connectionString _logger.LogInformation(connectionString); //将connection String 写入到日志文件中}}
}
DI容器管理配置文件Section
上面示例, 我们通过 _configuration.GetConnectionString("oeeDb")? 可以拿到connectionString, 非常方便, 这主要是得益于.Net 已经类库已经考虑到在配置文件中存储 connectionString 是一个普遍的做法, 所以类库内置支持了.
如果在 appsettings.json 中存一些自定义的信息, 如何方便读取呢? 微软推荐的 Options 模式, 下面详细介绍.
首先安装库:
- Microsoft.Extensions.Options.ConfigurationExtensions 库,? 为DI容器增加了从配置文件中实例化对象的能力, 即? serviceCollection.Configure<TOptions>(IConfiguration)
- Microsoft.Extensions.Options 库,? 提供以强类型的方式读取configuration文件, 这是.Net中首选的读取configuration文件方式.
假设 appsettings.json 中要存放appKey和appSecret信息, 具体配置如下:
"AppServiceOptions": {"appKey": "appkey1","appSecret": "appSecret1"}
定义对应的 Poco Class,? 推荐后缀为 Options,
public class AppServiceOptions{public string AppKey { get; set; } = "";public string AppSecret { get; set; } = "";
}</pre>
注册函数 ConfigureServices()中,? 注册 AppServiceOptions 类, 告知DI容器, 要基于配置文件AppServiceOptions section来实例化
private static void ConfigureServices(ServiceCollection services){//注册 FormMain 类services.AddScoped<FormMain>();
//register configurationIConfigurationBuilder cfgBuilder = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("appsettings.json").AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT")}.json", optional: true, reloadOnChange: false);IConfiguration configuration=cfgBuilder.Build();services.AddSingleton<IConfiguration>(configuration);//Create logger instancevar serilogLogger = new LoggerConfiguration().ReadFrom.Configuration(configuration).Enrich.FromLogContext().CreateLogger();//register loggerservices.AddLogging(builder => {object p = builder.AddSerilog(logger: serilogLogger, dispose: true);});//注册 AppServiceOptions 类, 告知DI容器, 要基于配置文件AppServiceOptions section来实例化services.AddOptions();services.Configure<AppServiceOptions>(configuration.GetSection("AppServiceOptions")); }</pre>
主动从DI容器中获取 AppServiceOptions 配置信息代码如下, 注意GetRequiredService函数的的泛型参数要使用 IOptions<> 包一下.
var appServiceOptionsWrapper=serviceProvider.GetRequiredService<IOptions<AppServiceOptions>>();AppServiceOptions appServiceOptions= appServiceOptionsWrapper.Value;
将 AppServiceOptions 注入到 FormMain 的代码, 和主动从DI容器中获取 AppServiceOptions 实例一样, 都需要使用 IOptions<> 接口包一下构造子形参.
public partial class FormMain : Form{ private readonly IConfiguration _configuration; private readonly ILogger _logger;private AppServiceOptions _appServiceOptions;
/// <summary>/// 为 FormMain 构造子增加三个形参, 构造子参数将由于DI容器自动注入/// </summary>/// <param name="configuration">形参必须是接口 IConfigurations</param>/// <param name="logger">形参必须是 ILogger泛型类型, 不能是 ILogger 类型</param>/// <param name="appServiceOptionsWrapper">形参必须是 IOptions 泛型接口 </param>public FormMain(IConfiguration configuration, ILogger<FormMain> logger, IOptions<AppServiceOptions> appServiceOptionsWrapper) {_configuration = configuration;_logger = logger;_appServiceOptions = appServiceOptionsWrapper.Value;InitializeComponent(); var connectionString = _configuration.GetConnectionString("oeeDb"); //从配置文件中读取oeeDb connectionString _logger.LogInformation(connectionString); //将connection String 写入到日志文件中}private void button1_Click(object sender, EventArgs e){this.Text = _appServiceOptions.AppKey;}
}</pre>
.net core 复杂 configuration Section 的读取
appsettings文件定义一个复杂的设置项, 顶层是一个json 数组, 里面又嵌套了另一个数组
"PlcDevices": [{"PlcDeviceId": "Plc1","IpAddress": "127.0.0.1","Port": 1234,"SlaveId": 1,"DataPoints": [{"ModbusAddress": 0,"EqpId": "eqp1"},{"ModbusAddress": 0,"EqpId": "eqp2"}]},
{"PlcDeviceId": "Plc2","IpAddress": "127.0.0.2","Port": 1234,"SlaveId": "2","DataPoints": [{"ModbusAddress": 0,"EqpId": "eqp3"},{"ModbusAddress": 0,"EqpId": "eqp4"}]
}
]
对应poco对象为:
public class PlcDevice
{public string IpAddress { get; set; } = "";public int Port { get; set; } = 0;public string PlcDeviceId { get; set; } = "";public int SlaveId { get; set; } public List<DataPoint> DataPoints { get; set; }
}
public class DataPoint
{ public int ModbusAddress { get; set; }
public string EqpId { get; set; } = “”;
}
读取 json 的C# 代码:
services.AddOptions();
//实例化一个对应 PlcDevices json 数组对象, 使用了 IConfiguration.Get<T>()
var PlcDeviceSettings= configuration.GetSection("PlcDevices").Get<List<PlcDevice>>();
//或直接通过 service.Configure<T>() 将appsettings 指定 section 放入DI 容器, 这里的T 为 List<PlcDevice>
services.Configure<List<PlcDevice>>(configuration.GetSection("PlcDevices"));
到此这篇关于.Net6开发winform程序使用依赖注入的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持菜鸟教程https://www.piaodoo.com/。
【无标题】.Net6开发winform程序使用依赖注入学习通http://www.bdgxy.com/相关推荐
- .Net6开发winform程序使用依赖注入学习通http://www.bdgxy.com/
文章来源: 学习通http://www.bdgxy.com/ 普学网http://www.boxinghulanban.cn/ 智学网http://www.jaxp.net/ 表格制作excel教程h ...
- 【无标题】.NET?MemoryCache如何清除全部缓存学习通http://www.bdgxy.com/
文章来源: 学习通http://www.bdgxy.com/ 普学网http://www.boxinghulanban.cn/ 智学网http://www.jaxp.net/ 表格制作excel教程h ...
- 【无标题】C#nbsp;语言入门基础介绍学习通http://www.bdgxy.com/
文章来源: 学习通http://www.bdgxy.com/ 普学网http://www.boxinghulanban.cn/ 智学网http://www.jaxp.net/ 表格制作excel教程h ...
- 【无标题】C# WPF如何反射加载Geometry几何图形数据图标学习通http://www.bdgxy.com/
文章来源: 学习通http://www.bdgxy.com/ 普学网http://www.boxinghulanban.cn/ 智学网http://www.jaxp.net/ 表格制作excel教程h ...
- 【无标题】如何在C#中使用Dapper ORM学习通http://www.bdgxy.com/
文章来源: 学习通http://www.bdgxy.com/ 普学网http://www.boxinghulanban.cn/ 智学网http://www.jaxp.net/ 表格制作excel教程h ...
- 在VS.NET中使用clickonce技术开发Winform程序
做为程序员,我们经常要面对的是对开发模式的选择,比如C/S模式和b/s模式.现在,很多人都似乎比较喜欢选择B/S模式进行web的开发,这其中的原因是很多的.但其中一点很重要的原因,那就是因为B/S开发 ...
- Angular 依赖注入学习笔记之工厂函数的用法
网址:https://angular.institute/di We can transfer any data through our apps, transform it and replace ...
- 【无标题】微信小程序:强制更新(测试编译)
如图,当小程序发布新的版本后,用户如果之前访问过该小程序,通过已打开的小程序进入(未手动删除),则会弹出这个提示,提醒用户更新新的版本.用户点击确定就可以自动重启更新,点击取消则关闭弹窗,不再更新. ...
- C# 开发winform程序 手机短信群发系统
手机短信群发作为企业日常通知,公告,天气预报等信息的一个发布平台,在于成本低,操作方便等诸多特点,成为企业通讯之首选.本文介绍短信的编码方式,AT指令以及用C#实现串口通讯的方法. 前言 目前,发送短 ...
最新文章
- 2020-09-21C++学习笔记之与C语言区别和加强——四种const意义(const int a; int const b; const int *c; int * const d)
- 资料收集新一代 Linux 文件系统 btrfs 简介
- eclipse中查看android源码
- ucache灾备云报价_UCACHE灾备云功能
- 问题 B: 编写函数:Swap (I) (Append Code)
- 华为云郑叶来:优势挡不住趋势,技术创新是主旋律
- mysql 索引列为Null的走不走索引及null在统计时的问题
- ZOJ 4028 15th浙江省省赛E. LIS(神奇贪心)
- poj 2356 Find a multiple dfs 爆搜!!!!
- bootstrapTable导出excel无响应问题
- 国内十大白银期货APP最新排名
- Grid++用程序定义报表模板(官方例子)
- 网络推广行业拓客的10个经典方法
- 浅析Promise的then方法
- 全国大学生物联网设计竞赛作品 | 室内消毒机器人-艾盾
- linux6 下dns配置,RHEL6中DNS配置
- 创业公司路演PPT模板
- 定了!阿里日成了“中国品牌日”! 老外说,原因都在这里了
- 开源SLAM方案评价与比较
- 腾讯万字Code Review规范出炉!别再乱写代码了
热门文章
- php毕业论文吧,浅谈PHP(毕业论文).docx
- Android5.x新特性之CardView立体卡片--阴影、圆角
- 战神笔记本ubuntu 18.04.1LTS cuda10.0安装折腾记
- 【LeetCode】罗马数字转整数
- C++ aop设计模式,动态横切的实现
- linux系统运行级别wq命令,Linux系统运行级别和关机重启命令介绍
- 关于SVG图片宽高被锁定无法拉伸问题处理
- android调用音量方法,android中获取当前音量大小
- java和php哪个更有发展前景_Java与php比较哪个更有发展
- 电子邮箱系统哪家好?邮箱登陆入口是?