.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