.Net6 winform 程序使用依賴注入


.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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM