繁体   English   中英

发送多个 appsettings.json 值的简单方法是通过工作人员发布到 .net 核心中的 API 值吗?

[英]Easy way to send multiple appsettings.json values through worker posting to API in .net core?

我正在.Net Core 3.1 中构建一个 C# Windows 服务 API 轮询应用程序。 这将在服务器上 24/7 运行,每 5 分钟轮询一次。

我想要一种更简单的方法来通过我的 API 后调用发送参数,方法是直接从我的 appsettings.json 的主体发送值,而不是为每个 object 创建新类和强类型。

我的应用程序目前适用于一个 appsettings object 给定以下代码

appsettings.json

    "ReceiptSettings": {
      "select_topx": "100",
      "tran_type": "REC",
      "sub_type": "PO",
      "max_age_min": "10000",
      "integration_name": "ERP"
    }

工人:

        public IConfiguration _configuration { get; private set; }

        ...

        public async Task StartAsync(CancellationToken cancellationToken)
        {
            _logger.LogInformation("Timed Hosted Service running.");

            _timer = new Timer(DoWork, Task.CompletedTask, TimeSpan.Zero,
                 TimeSpan.FromMinutes(5));

            await Task.CompletedTask;
        }

        private async void DoWork(object state)
        {

            // Keep garbage collector from collecting and stopping timer
            GC.KeepAlive(_timer);

            // Don't let timer execute again if we are still processing last iteration
            if (Monitor.TryEnter(_locker))
            {
                try
                {
                   RunPoller();
                }
                finally
                {
                    Monitor.Exit(_locker);
                }
            }
        }

        private async void RunPoller()
        {
            var count = Interlocked.Increment(ref executionCount);

            // Do long running work here
            _logger.LogInformation($"Polling started. Iteration: {count}");
            await Task.Run(() => RunPoller.Run(_logger, _apiSettings, _configuration));

        }

运行轮询器:

        public static IConfiguration _iConfiguration { get; private set; }

        public static async Task Run(ILogger<Worker> logger, IOptions<APIConfiguration> apiSettings, IConfiguration configuration)
        {

        ...

            try
            {
                Dictionary<string, object> settings = _config
                    .GetSection("ReceiptSettings")
                    .Get<Dictionary<string, object>>();
                string json = JsonConvert.SerializeObject(_settings);
                var payload = new StringContent(json, Encoding.UTF8, "application/json");
                ...
            }

        ...

我想重构它以遍历 PollingSettings object,根据值为 PollingSettings 中的每个设置创建一个新线程

"PollingSettings": {
    "ReceiptSettings": {
      "select_topx": "100",
      "tran_type": "REC",
      "sub_type": "PO",
      "max_age_min": "10000",
      "integration_name": "ERP"
    },
    "InventorySettings": {
      "select_topx": "100",
      "tran_type": "IN",
      "sub_type": "ADJ",
      "mark_pickup_id": "1"
    }

我已经有强类型的 apiSettings 并且可以做到这一点。 但我必须在 Visual Studio 中对对象和类进行更改。 如果我要通过这种方法动态发送它们,那么我可以在记事本中打开 appsettings.json 文件并在更短的时间内修改参数。

我已经尝试过了,但是我收到 null 值错误,并且第一次迭代不会触发 RunPoller class:

        private async void DoWork(object state)
        {

            // Keep garbage collector from collecting and stopping timer
            GC.KeepAlive(_timer);

            var pollingConfigs = Configuration.GetSection("PollingSettings").GetChildren();

            // Don't let timer execute again if we are still processing last iteration
            if (Monitor.TryEnter(_locker))
            {
                try
                {
                    foreach (var setting in pollingConfigs)
                    {
                        Dictionary<string, object> settings = Configuration
                                                               .GetSection(setting.Key)
                                                               .Get<Dictionary<string, object>>();
                        RunPoller(settings);
                    }
                }
                finally
                {
                    Monitor.Exit(_locker);
                }
            }
        }

        private async void RunPoller(Dictionary<string, object> settings)
        {

            // Do long running work here
            _logger.LogInformation($"Polling started. Iteration: {count}");
            await Task.Run(() => RunPoller.Run(_logger, _apiSettings, settings));

        }

(为 RunPoller.Run 的设置保留 DI,为简洁起见删除了代码。)

有没有办法正确地做到这一点?

对于现有代码,您只需更改获取子部分的路径,如以下代码:
1 - 按Path更改.GetSection(setting.Key)Key

var pollingConfigs = Configuration.GetSection("PollingSettings").GetChildren();

// Don't let timer execute again if we are still processing last iteration
if (Monitor.TryEnter(_locker))
{
    try
    {
        foreach (var setting in pollingConfigs)
        {
            Dictionary<string, object> settings = Configuration
                                                   .GetSection(setting.Path)
                                                   .Get<Dictionary<string, object>>();
            RunPoller(settings);
        }
    }
    finally
    {
        Monitor.Exit(_locker);
    }
}

2 - 你也可以使用这个解决方案:
2.1 获取Dictionary<string, object>

var pollingConfigs = _configuration.GetSection("PollingSettings")
    .GetChildren()
    .Select(y => y.Get<Dictionary<string, object>>());

2.2并在循环中,直接使用列表的值:

foreach (Dictionary<string, object> setting in pollingConfigs)
{
    RunPoller(setting);
}

我希望你觉得这有帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM