文章来源: 学习通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&lt;FormMain&gt;();   //主动从容器中获取FormMain实例, 这是简洁写法// var formMain = (FormMain)serviceProvider.GetService(typeof(FormMain));  //更繁琐的写法Application.Run(formMain); }/// &lt;summary&gt;/// 在DI容器中注册所有的服务类型 /// &lt;/summary&gt;/// &lt;param name="services"&gt;&lt;/param&gt;private static void ConfigureServices(ServiceCollection services){//注册 FormMain 类services.AddScoped&lt;FormMain&gt;();//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&lt;IConfiguration&gt;(configuration);//Create logger instancevar serilogLogger = new LoggerConfiguration().ReadFrom.Configuration(configuration).Enrich.FromLogContext().CreateLogger();//register loggerservices.AddLogging(builder =&gt; {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;

    /// &lt;summary&gt;/// 为 FormMain 构造子增加两个形参, 构造子参数将由于DI容器自动注入/// &lt;/summary&gt;/// &lt;param name="configuration"&gt;&lt;/param&gt;/// &lt;param name="logger"&gt;形参必须是 ILogger泛型类型, 不能是 ILogger 类型&lt;/param&gt;public FormMain(IConfiguration configuration, ILogger&lt;FormMain&gt; 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&lt;IConfiguration&gt;(configuration);//Create logger instancevar serilogLogger = new LoggerConfiguration().ReadFrom.Configuration(configuration).Enrich.FromLogContext().CreateLogger();//register loggerservices.AddLogging(builder =&gt; {object p = builder.AddSerilog(logger: serilogLogger, dispose: true);});//注册 AppServiceOptions 类, 告知DI容器, 要基于配置文件AppServiceOptions section来实例化services.AddOptions();services.Configure&lt;AppServiceOptions&gt;(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;
    /// &lt;summary&gt;/// 为 FormMain 构造子增加三个形参, 构造子参数将由于DI容器自动注入/// &lt;/summary&gt;/// &lt;param name="configuration"&gt;形参必须是接口 IConfigurations&lt;/param&gt;/// &lt;param name="logger"&gt;形参必须是 ILogger泛型类型, 不能是 ILogger 类型&lt;/param&gt;/// &lt;param name="appServiceOptionsWrapper"&gt;形参必须是 IOptions 泛型接口 &lt;/param&gt;public FormMain(IConfiguration configuration, ILogger&lt;FormMain&gt; logger, IOptions&lt;AppServiceOptions&gt; 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/相关推荐

  1. 【无标题】.Net6开发winform程序使用依赖注入学习通http://www.bdgxy.com/

    文章来源: 学习通http://www.bdgxy.com/ 普学网http://www.boxinghulanban.cn/ 智学网http://www.jaxp.net/ 表格制作excel教程h ...

  2. 【无标题】C#nbsp;语言入门基础介绍学习通http://www.bdgxy.com/

    文章来源: 学习通http://www.bdgxy.com/ 普学网http://www.boxinghulanban.cn/ 智学网http://www.jaxp.net/ 表格制作excel教程h ...

  3. 【无标题】C# WPF如何反射加载Geometry几何图形数据图标学习通http://www.bdgxy.com/

    文章来源: 学习通http://www.bdgxy.com/ 普学网http://www.boxinghulanban.cn/ 智学网http://www.jaxp.net/ 表格制作excel教程h ...

  4. 【无标题】如何在C#中使用Dapper ORM学习通http://www.bdgxy.com/

    文章来源: 学习通http://www.bdgxy.com/ 普学网http://www.boxinghulanban.cn/ 智学网http://www.jaxp.net/ 表格制作excel教程h ...

  5. 【无标题】.NET?MemoryCache如何清除全部缓存学习通http://www.bdgxy.com/

    文章来源: 学习通http://www.bdgxy.com/ 普学网http://www.boxinghulanban.cn/ 智学网http://www.jaxp.net/ 表格制作excel教程h ...

  6. 如何从dump文件中提取出C#源代码学习通http://www.bdgxy.com/

    文章来源: 学习通http://www.bdgxy.com/ 普学网http://www.boxinghulanban.cn/ 智学网http://www.jaxp.net/ 表格制作excel教程h ...

  7. CC#中List用法介绍详解学习通http://www.bdgxy.com/roundWorker类用法总结学习通http://www.bdgxy.com/

    文章来源: 学习通http://www.bdgxy.com/ 普学网http://www.boxinghulanban.cn/ 智学网http://www.jaxp.net/ 表格制作excel教程h ...

  8. C#实现将PDF转为线性化PDF学习通http://www.bdgxy.com/

    文章来源: 学习通http://www.bdgxy.com/ 普学网http://www.boxinghulanban.cn/ 智学网http://www.jaxp.net/ 表格制作excel教程h ...

  9. C#实现时间戳与标准时间的互转学习通http://www.bdgxy.com/

    文章来源: 学习通http://www.bdgxy.com/ 普学网http://www.boxinghulanban.cn/ 智学网http://www.jaxp.net/ 表格制作excel教程h ...

最新文章

  1. CentOS基础网络配置路由和默认网关
  2. Python内置函数filter()和匿名函数lambda解析
  3. AT5160-[AGC037C]Numbers on a Circle【贪心,堆】
  4. php 转换数组为小写,PHP如何将数组键转换为小写?
  5. c语言如何将程序保存在文件,急求如何将下列C语言程序数据存储到文件中?
  6. java javax.xml.ws_如何通过javax.xml.ws.Service进行调用
  7. 论文浅尝 - 计算机工程 | 大规模企业级知识图谱实践综述
  8. c语言设计指导实训,C语言程序设计实训指导
  9. 逆向某网站sign签名算法
  10. Asp.net MVC3.0 入门指南 6 审视编辑方法和视图
  11. 航天生物计算机新能源你对哪个领域的课,写作《语言简明》课件.ppt
  12. 德勤 oracle par面,经验 | 德勤19par面合集+楼主新鲜audit par面经验
  13. 用户帐户控制---为了对电脑进行保护,已经阻止此应用。---管理员已阻止你运行此应。有关详细信息,请与管理员联系。
  14. 面向未来的大数据核心技术都有什么?
  15. redmi路由器是linux,拯救小米路由器硬盘数据的方法及软件下载
  16. UE4材质(二):PBR材质
  17. 主流浏览器有哪些?这些浏览器的内核分别是什么?
  18. Git——git的简单使用以及连接gitee的远程仓库[经验 y.2]
  19. 玄幻:开局选择瑶池,我只想默默签到!(一)
  20. 在windows下编译Botan

热门文章

  1. 一键就能去除视频水印,简单实用,重点是免费的哦!
  2. 半入耳式真无线蓝牙耳机测评,南卡和漫步者蓝牙耳机哪个音质更好?
  3. 如何制作微信公众号中的服务号以及订阅号
  4. Android 实现简单的帧动画
  5. Win10任务栏的蓝牙图标误删,如何恢复?
  6. 阿里巴巴专家亲自撰写,Dubbo 3.0 分布式实战(彩印版)
  7. java字符串转对象数组_将字符串数组转为java对象
  8. cv2.ADAPTIVE_THRESH_GAUSSIAN_C作用是什么
  9. 5分钟实现百度首页搜索框,可能吗?
  10. fm2017 1731 ajax,FM2017开档必签热门推荐.doc