D-12 设定挡 ? configuration ? IOptionsMonitor

设定档

昨日说明关於使用者身分验证以及权限设定的部分加以说明,并且透过第三方插件的方式展现如何在dotnetcore里面实作jwt的协定,然而今天会处理甚麽问题呢,请大家看下去。

本文同步放置於此

如何处理设定档

「糟糕,我要怎麽去把连线串抽出去给SRE设定阿。」
一大早小光到公司时就看到大头似乎又遇到了问题,可能是昨天写的东西需要连线到资料库但是没有地方可以存放连线串。
「前辈阿,我要把连线串放哪里啊?」
这时候大头直接走向老K那边,直接跟老K请教关於连线串该如何处理。
「很简单啊,你就放文字档就好了啊,到时再去读取文字档即可。」
听到老K的说明後大头似乎有想法的回到座位上准备开始开发的样子,这时老K快步走到大头身边。
「等等~~~你准备怎麽做阿,应该不是写一个读档的功能然後把资料放在记忆体里面吧。」
大头的表情一副是你怎麽知道,然後就是有甚麽问题吗。
「唉,你又想要自己处理设定资料得存放跟动态加载吗,其实你只要使用IOptionsMonitor跟Configuration就搞定了。」
不过老K说了之後对於大头而言好像甚麽都没说的样子,所以老K就卷起袖子准备大展身手的样子。
「来吧我示范给你看吧。」

Configuration

所以首先第一动是先把档案加载进来放在记忆体里面,这部分就是dotnetcore内建的设定档的部分,这部分首先是在Program.CreateHostBuilder加入以下内容。

public static IWebHostBuilder CreateHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseContentRoot(Directory.GetCurrentDirectory())
        .ConfigureAppConfiguration((hostingContext, config) =>
        {
            config.AddJsonFile(
                "Settings/CommonSetting.json", optional: false, reloadOnChange: true);
        });

首先UseContentRoot是设定网页服务器的跟目录,ConfigureAppConfiguration传的Lambda就是要载入的设定档,其中:

  • optional -> 是否为选用,如果一定要有这当案就把他设成false但是如过不需要强制读这档案就设成true
  • reloadOnChange -> 是否支援动态加载,存档後记忆体内档案内容会更新。

接下来如果要依据环境不同资料要不同的话请看下列范例。

.ConfigureAppConfiguration((hostingContext, config) =>
{
    config.AddJsonFile(
        "Settings/CommonSetting.json", optional: false, reloadOnChange: true);
    var env = hostingContext.HostingEnvironment;
    config.AddJsonFile(
        $"Settings/CommonSetting.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
});

如此可以取得环境变数HostingEnvironment,所以只要在多一个CommonSetting.SIT.json就可以在SIT环境使用了。

IOptionsMonitor

如果不介意直接相依於Configuration以及不会觉得取出来资料还要解析的朋友们恭喜了,因为本篇的内容到上面就结束了。不过想要需要将设定档解析成类别物件的就继续看下去。
接下来要说明选项模式,在继续下去之前要请大家先安装下面的套件。

dotnet add package Microsoft.Extensions.Options

然後接下来要先说明选项模式中的三种模式

IOptions 档案变动时资料不会跟着变动
IOptionsSnapshot 注入之後内容就不会变动,但是档案异动後所注入的资料就是异动後的资料
IOptionsMonitor 支援热重载,可以适用在单例(Singleton)模式的物件

在说明完种类後现在要开始说明如何把资料放到选项模式物件中。

Configuration跟IOptionsMonitor的桥接

这部分说明怎麽把资料从Configuration注册到IOptionsMonitor物件中,

首先我们先定义一个类别如下,

public class CommonSetting
{
    public string Connection { get; set; }
}

接下来要再Startup.ConfigureServices加入以下内容。

services.AddOptions();
services.Configure<CommonSetting>(Configuration.GetSection("CommonSetting"));
services.Configure<List<CommonSetting>>(Configuration.GetSection("CommonSettings"));

所以当你的设定档中有以下内容就可以取得资料并成功注入

{
  "CommonSetting":{
      "Connections":"....."
  }
  "CommonSettings": [{
       "Connections":"....."
     },{
       "Connections":"....."
     }
  ],
}

最後以IOptionsMonitor为例说明如何在物件时例中使用,请先看以下说明。

public class HomeController : Controller
{
    private readonly IOptionsMonitor<CommonSetting> _setting;
	
	private readonly IOptionsMonitor<List<CommonSetting>> _settings;

    public HomeController(IOptionsMonitor<CommonSetting> setting,
	    IOptionsMonitor<List<CommonSetting>> settings)
    {
        setting = _setting;
        settings = _settings;
    }

    public IActionResult Index()
    {
        _setting.CurrentValue.Connection;
        foreach(var item in _settings.CurrentValue)
        {
        }
    }
}

简单说明就是透过建构子注入之後使用.CurrentValue可以取的最新的资料并做对应的使用即可。

後记

今天跟大家介绍如果有需要使用设定档该如何透过Microsoft.Extensions.Options这个套件来解析设定档并且当设定档异动时可以取得异动後的资讯,希望能对大家的开发有所帮助。


<<:  设定档格式 YAML

>>:  Day 21 总要接受外部的刺激

【PHP Telegram Bot】Day10 - Long Polling、持续接收与发送讯息

昨天有讲到一个叫做 getUpdates 的方法,但我们没有填任何参数,今天要利用 offset 与...

【Day 25】NumPy (2)

前言 今天要来继续介绍关於 NumPy 的应用。 资料型态、数学运算等等 NumPy Datatyp...

冒险村25 - Design Pattern(5) - Service Object

25 - Design Pattern(5) - Service Object Service 相对...

[Day_8]资料储存容器 (2) - 串列(list)_(1)

今天要来跟大家介绍串列(list), 串列为可修改的序列资料, 可以修改元素资料、新增、删除、插入、...

Day 13 | 魔术方块AR游戏开发Part2 - 魔术方块侦测

在上一篇文章中,我们完成魔术方块的建立及旋转,今天我们要来完成魔术方块的侦测。 目录 魔术方块的侦测...