欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

.Net6開發(fā)winform程序使用依賴注入

 更新時間:2021年12月22日 15:20:01   作者:harrychinese  
本文詳細講解了.Net6開發(fā)winform程序使用依賴注入的方法,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下

.net? Blazor webassembly 和 webAPI 內(nèi)建支持依賴注入, Winform 和 Console 應用雖然不帶有依賴注入功能, 但增加依賴注入也很簡單.?

本文將示例如何為 WinForm 程序增加依賴注入特性, 實現(xiàn)通過DI容器獲取Cofiguration 實例, 并讀取appsettings.json文件.

安裝依賴庫, 有點多

  • Microsoft.Extensions.DependencyInjection 庫, 依賴注入的類庫
  • Microsoft.Extensions.Configuration 庫, 包含IConfiguration接口 和 Configuration類
  • Microsoft.Extensions.Configuration.Json 庫, 為 IConfiguration 增加了讀取 Json 文件功能,
  • Microsoft.Extensions.Hosting 庫,? 提供 Host 靜態(tài)類,? 有能力從 appsettings.{env.EnvironmentName}.json 加載相應 env? 的設(shè)定值,? 并將設(shè)定值用于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, 頂層節(jié)點要求是 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 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 構(gòu)造子增加兩個形參, 構(gòu)造子參數(shù)將由于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 已經(jīng)類庫已經(jīng)考慮到在配置文件中存儲 connectionString 是一個普遍的做法, 所以類庫內(nèi)置支持了.

如果在 appsettings.json 中存一些自定義的信息, 如何方便讀取呢? 微軟推薦的 Options 模式, 下面詳細介紹.

首先安裝庫:

  • Microsoft.Extensions.Options.ConfigurationExtensions 庫,? 為DI容器增加了從配置文件中實例化對象的能力, 即? serviceCollection.Configure<TOptions>(IConfiguration)
  • Microsoft.Extensions.Options 庫,? 提供以強類型的方式讀取configuration文件, 這是.Net中首選的讀取configuration文件方式.

假設(shè) 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; } = "";

    }

注冊函數(shù) ConfigureServices()中,? 注冊 AppServiceOptions 類, 告知DI容器, 要基于配置文件AppServiceOptions section來實例化

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);
            });


            //注冊 AppServiceOptions 類, 告知DI容器, 要基于配置文件AppServiceOptions section來實例化
            services.AddOptions();
            services.Configure<AppServiceOptions>(configuration.GetSection("AppServiceOptions"));    
        }

主動從DI容器中獲取 AppServiceOptions 配置信息代碼如下, 注意GetRequiredService函數(shù)的的泛型參數(shù)要使用 IOptions<> 包一下.

   var appServiceOptionsWrapper=serviceProvider.GetRequiredService<IOptions<AppServiceOptions>>();
   AppServiceOptions appServiceOptions= appServiceOptionsWrapper.Value;

將 AppServiceOptions 注入到 FormMain 的代碼, 和主動從DI容器中獲取 AppServiceOptions 實例一樣, 都需要使用 IOptions<> 接口包一下構(gòu)造子形參.

public partial class FormMain : Form
    { 
        private readonly IConfiguration _configuration; 
        private readonly ILogger _logger;
        private AppServiceOptions _appServiceOptions;

        /// <summary>
        /// 為 FormMain 構(gòu)造子增加三個形參, 構(gòu)造子參數(shù)將由于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;
        }
    }

.net core 復雜 configuration Section 的讀取

appsettings文件定義一個復雜的設(shè)置項, 頂層是一個json 數(shù)組, 里面又嵌套了另一個數(shù)組

"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 數(shù)組對象, 使用了 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"));

到此這篇關(guān)于.Net6開發(fā)winform程序使用依賴注入的文章就介紹到這了。希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評論