WebEnh

.net7 mvc jquery bootstrap json 学习中 第一次学PHP,正在研究中。自学进行时... ... 我的博客 https://enhweb.github.io/ 不错的皮肤:darkgreentrip,iMetro_HD
  首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

.Net6 winform 程序使用依赖注入

Posted on 2022-01-21 10:08  WebEnh  阅读(1051)  评论(0编辑  收藏  举报

.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 信息

 

========================================

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 configuration
IConfigurationBuilder 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 instance
var serilogLogger = new LoggerConfiguration()
.ReadFrom.Configuration(configuration)
.Enrich.FromLogContext()
.CreateLogger();

//register logger
services.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容器如何实例化一个带参数的类

========================================

上面实例中 FormMain 的构造子, 仅仅含有DI容器中已有的对象, 所以在DI实例化对象时, 我们不需要关注太多就可以. 但如果 FormMain 还有其他参数, FormMain 类将如何被DI 容器管理呢?

安装 Microsoft.Extensions.Options 库, 可参考: https://csharp.christiannagel.com/2016/07/27/diwithoptions/
————————————————
版权声明:本文为CSDN博主「csdnharrychinese」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/csdnharrychinese/article/details/121463976