diff --git a/Sln.Wcs.HoistAdapter/Domain/Model/GetHoistStatus/GetHoistStatusResultModel.cs b/Sln.Wcs.HoistAdapter/Domain/Model/GetHoistStatus/GetHoistStatusResultModel.cs
index 3896b1f..03cecc8 100644
--- a/Sln.Wcs.HoistAdapter/Domain/Model/GetHoistStatus/GetHoistStatusResultModel.cs
+++ b/Sln.Wcs.HoistAdapter/Domain/Model/GetHoistStatus/GetHoistStatusResultModel.cs
@@ -43,39 +43,44 @@ public class GetHoistStatusResultModel
public string hoistCode { get; set; }
///
- /// 反馈任务执行指令:是否可以下发任务
+ /// 设备参数
///
- public int canDispatchTask { get; set; }
-
- ///
- /// 当前楼层
- ///
- public int currentFloor { get; set; }
-
- ///
- /// 接驳位状态(1~5 楼)
- /// 索引 0 → 1楼,索引 1 → 2楼,... 索引 4 → 5楼
- ///
- public int[] transferStationStatus { get; set; } = new int[5];
-
- ///
- /// 读写器触发状态(1~5 楼)
- /// 索引 0 → 1楼,索引 1 → 2楼,... 索引 4 → 5楼
- ///
- public int[] readerTriggerStatus { get; set; } = new int[5];
-
- ///
- /// 自动状态:true = 自动模式,false = 手动模式
- ///
- public int isAutoMode { get; set; }
-
- ///
- /// 屏蔽调度:true = 屏蔽中,false = 未屏蔽
- ///
- public int isDispatchBlocked { get; set; }
-
- ///
- /// 状态指示(详见 )
- ///
- public int stateIndicator { get; set; }
+ public string deviceParamStr{get;set;}
+
+ // ///
+ // /// 反馈任务执行指令:是否可以下发任务
+ // ///
+ // public int canDispatchTask { get; set; }
+ //
+ // ///
+ // /// 当前楼层
+ // ///
+ // public int currentFloor { get; set; }
+ //
+ // ///
+ // /// 接驳位状态(1~5 楼)
+ // /// 索引 0 → 1楼,索引 1 → 2楼,... 索引 4 → 5楼
+ // ///
+ // public int[] transferStationStatus { get; set; } = new int[5];
+ //
+ // ///
+ // /// 读写器触发状态(1~5 楼)
+ // /// 索引 0 → 1楼,索引 1 → 2楼,... 索引 4 → 5楼
+ // ///
+ // public int[] readerTriggerStatus { get; set; } = new int[5];
+ //
+ // ///
+ // /// 自动状态:true = 自动模式,false = 手动模式
+ // ///
+ // public int isAutoMode { get; set; }
+ //
+ // ///
+ // /// 屏蔽调度:true = 屏蔽中,false = 未屏蔽
+ // ///
+ // public int isDispatchBlocked { get; set; }
+ //
+ // ///
+ // /// 状态指示(详见 )
+ // ///
+ // public int stateIndicator { get; set; }
}
\ No newline at end of file
diff --git a/Sln.Wcs.HoistAdapter/Service/Impl/HoistService.cs b/Sln.Wcs.HoistAdapter/Service/Impl/HoistService.cs
index f987d55..cc2a5c5 100644
--- a/Sln.Wcs.HoistAdapter/Service/Impl/HoistService.cs
+++ b/Sln.Wcs.HoistAdapter/Service/Impl/HoistService.cs
@@ -179,6 +179,7 @@ public class HoistService:IHoistService
code = resp.code,
message = resp.message,
hoistCode = resp.hoistCode,
+ deviceParamStr = resp.deviceParamStr
},
};
diff --git a/Sln.Wcs.HoistDispatcher/Dispatcher.cs b/Sln.Wcs.HoistDispatcher/HoistDispatcher.cs
similarity index 74%
rename from Sln.Wcs.HoistDispatcher/Dispatcher.cs
rename to Sln.Wcs.HoistDispatcher/HoistDispatcher.cs
index 946aab6..e16993b 100644
--- a/Sln.Wcs.HoistDispatcher/Dispatcher.cs
+++ b/Sln.Wcs.HoistDispatcher/HoistDispatcher.cs
@@ -23,6 +23,7 @@
#endregion << 版 本 注 释 >>
+using Newtonsoft.Json;
using Sln.Wcs.HoistAdapter.Domain.Dto.GetHoistStatus;
using Sln.Wcs.HoistAdapter.Domain.Enum;
using Sln.Wcs.HoistAdapter.Service;
@@ -33,11 +34,11 @@ using Sln.Wcs.Serilog;
namespace Sln.Wcs.HoistDispatcher;
-public class Dispatcher
+public class HoistDispatcher
{
private readonly SerilogHelper _logger;
private readonly IHoistService _hoistAdapter;
- public Dispatcher(IHoistService hoistAdapter, SerilogHelper logger)
+ public HoistDispatcher(IHoistService hoistAdapter, SerilogHelper logger)
{
_hoistAdapter = hoistAdapter;
_logger = logger;
@@ -88,8 +89,24 @@ public class Dispatcher
// 1、读取 RFID 条码
// 2、下发提升机任务:起点、终点
// 3、等待提升机完成任务
-
+ RefreshDeviceParams(hostCode,out List deviceInfos);
}
-
+
+
+ public void RefreshDeviceParams(string hostCode,out List deviceParams)
+ {
+ deviceParams = null;
+
+ GetHoistStatusResultDto getRes = _hoistAdapter.GetHoistStatus(new GetHoistStatusDto(){hoistCode = hostCode});
+
+ if (getRes.code == HoistStatusEnum.成功)
+ {
+ deviceParams = JsonConvert.DeserializeObject>(getRes.data.deviceParamStr);
+ }
+ else
+ {
+ _logger.Info($"设备参数获取失败:{getRes.msg}");
+ }
+ }
}
\ No newline at end of file
diff --git a/Sln.Wcs.HoistDispatcher/HoistListener.cs b/Sln.Wcs.HoistDispatcher/HoistListener.cs
deleted file mode 100644
index 188e2d3..0000000
--- a/Sln.Wcs.HoistDispatcher/HoistListener.cs
+++ /dev/null
@@ -1,123 +0,0 @@
-#region << 版 本 注 释 >>
-
-/*--------------------------------------------------------------------
-* 版权所有 (c) 2026 WenJY 保留所有权利。
-* CLR版本:4.0.30319.42000
-* 机器名称:Mr.Wen's MacBook Pro
-* 命名空间:Sln.Wcs.HoistDispatcher
-* 唯一标识:E94B669C-DB45-4891-B01E-43E80B790AFB
-*
-* 创建者:WenJY
-* 电子邮箱:
-* 创建时间:2026-06-01 17:50:44
-* 版本:V1.0.0
-* 描述:
-*
-*--------------------------------------------------------------------
-* 修改人:
-* 时间:
-* 修改说明:
-*
-* 版本:V1.0.0
-*--------------------------------------------------------------------*/
-
-#endregion << 版 本 注 释 >>
-
-using Sln.Wcs.HoistAdapter.Domain.Dto.GetHoistStatus;
-using Sln.Wcs.HoistAdapter.Domain.Model.GetHoistStatus;
-using Sln.Wcs.HoistAdapter.Service;
-using Sln.Wcs.Model.Domain;
-using Sln.Wcs.Repository.service;
-
-namespace Sln.Wcs.HoistDispatcher;
-
-public class HoistListener
-{
- private readonly IHoistService _hoistAdapter;
-
- public delegate void RefreshHoistStatus(List hoistStatusResult);
- public static event RefreshHoistStatus RefreshHoistStatusEvent;
-
- public HoistListener(IHoistService hoistAdapter)
- {
- _hoistAdapter = hoistAdapter;
- }
-
- public void Run(List paramInfo)
- {
- bool isflag = true;
- do
- {
- List result = new List();
- paramInfo.ForEach(x =>
- {
- try
- {
- GetHoistStatusResultDto hoistStatus = _hoistAdapter.GetHoistStatus(new GetHoistStatusDto()
- {
- hoistCode = x.hoistCode,
- canDispatchTask = x.canDispatchTask,
- currentFloor = x.currentFloor,
- transferStationStatus = x.transferStationStatus,
- readerTriggerStatus = x.readerTriggerStatus,
- isDispatchBlocked = x.isDispatchBlocked,
- stateIndicator = x.stateIndicator,
- });
- result.Add(hoistStatus);
- }
- catch (Exception e)
- {
- isflag = false;
- }
- });
-
- RefreshHoistStatusEvent?.Invoke(result);
- } while (isflag);
- }
-
- // private List GetPlcParams()
- // {
- // List deviceInfos = _deviceInfoService.GetDeviceInfos(x => x.isFlag == 1).ToList();
- // List plcParams = new List();
- //
- // foreach (var item in deviceInfos)
- // {
- // dynamic virtualEntity = new System.Dynamic.ExpandoObject();
- // virtualEntity.hoistCode = item.deviceCode;
- // virtualEntity.hostCode = item.hostCode;
- // virtualEntity.deviceNumber = item.deviceName.Contains("1#") ? 1 : 2;
- // if (item.deviceParams != null)
- // {
- // string canDispatchTask = item.deviceParams.Where(x => x.paramName .Contains("提升机反馈任务状态")).Select(x => x.paramAddress)
- // .FirstOrDefault();
- // string currentFloor = item.deviceParams.Where(x => x.paramName .Contains("提升机当前层")).Select(x => x.paramAddress)
- // .FirstOrDefault();
- // List transferStationStatus = item.deviceParams.Where(x => x.paramName .Contains("接驳位状态")).Select(x => x.paramAddress)
- // .ToList();
- // List readerTriggerStatus = item.deviceParams.Where(x => x.paramName .Contains("读写器读取触发")).Select(x => x.paramAddress)
- // .ToList();
- // string isDispatchBlocked = item.deviceParams.Where(x => x.paramName .Contains("提升机屏蔽调度")).Select(x => x.paramAddress)
- // .FirstOrDefault();
- // string stateIndicator = item.deviceParams.Where(x => x.paramName .Contains("提升机状态指示")).Select(x => x.paramAddress)
- // .FirstOrDefault();
- // virtualEntity.canDispatchTask = canDispatchTask;
- // virtualEntity.currentFloor = currentFloor;
- // virtualEntity.transferStationStatus = transferStationStatus;
- // virtualEntity.readerTriggerStatus = readerTriggerStatus;
- // virtualEntity.isDispatchBlocked = isDispatchBlocked;
- // virtualEntity.stateIndicator = stateIndicator;
- // }
- // else
- // {
- // virtualEntity.canDispatchTask = string.Empty;
- // virtualEntity.currentFloor = string.Empty;
- // virtualEntity.transferStationStatus = string.Empty;
- // virtualEntity.readerTriggerStatus = string.Empty;
- // virtualEntity.isDispatchBlocked = string.Empty;
- // virtualEntity.stateIndicator = string.Empty;
- // }
- // plcParams.Add(virtualEntity);
- // }
- // return plcParams;
- // }
-}
\ No newline at end of file
diff --git a/Sln.Wcs.HoistSdk/Config/HoistConfig.cs b/Sln.Wcs.HoistSdk/Config/HoistConfig.cs
index 2b78fa5..2866f7b 100644
--- a/Sln.Wcs.HoistSdk/Config/HoistConfig.cs
+++ b/Sln.Wcs.HoistSdk/Config/HoistConfig.cs
@@ -30,6 +30,8 @@ namespace Sln.Wcs.HoistSdk.Config;
public class HoistConfig
{
public readonly string hoist_control_addr = "";
+
+ public readonly string hoist_plc_param = "";
///
/// 注入提升机配置文件
@@ -49,5 +51,7 @@ public class HoistConfig
}
hoist_control_addr = configuration["提升机控制地址"];
+
+ hoist_plc_param = configuration["PLC参数"];
}
}
\ No newline at end of file
diff --git a/Sln.Wcs.HoistSdk/Dto/GetHoistStatus/GetHoistStatusResultDto.cs b/Sln.Wcs.HoistSdk/Dto/GetHoistStatus/GetHoistStatusResultDto.cs
index 9dbcfb6..d50ba6f 100644
--- a/Sln.Wcs.HoistSdk/Dto/GetHoistStatus/GetHoistStatusResultDto.cs
+++ b/Sln.Wcs.HoistSdk/Dto/GetHoistStatus/GetHoistStatusResultDto.cs
@@ -46,37 +46,42 @@ public class GetHoistStatusResultDto
///
/// 反馈任务执行指令:是否可以下发任务
///
- public int canDispatchTask { get; set; }
+ //public int canDispatchTask { get; set; }
///
/// 当前楼层
///
- public int currentFloor { get; set; }
+ //public int currentFloor { get; set; }
///
/// 接驳位状态(1~5 楼)
/// 索引 0 → 1楼,索引 1 → 2楼,... 索引 4 → 5楼
///
- public int[] transferStationStatus { get; set; } = new int[5];
+ //public int[] transferStationStatus { get; set; } = new int[5];
///
/// 读写器触发状态(1~5 楼)
/// 索引 0 → 1楼,索引 1 → 2楼,... 索引 4 → 5楼
///
- public int[] readerTriggerStatus { get; set; } = new int[5];
+ //public int[] readerTriggerStatus { get; set; } = new int[5];
///
/// 自动状态:true = 自动模式,false = 手动模式
///
- public int isAutoMode { get; set; }
+ //public int isAutoMode { get; set; }
///
/// 屏蔽调度:true = 屏蔽中,false = 未屏蔽
///
- public int isDispatchBlocked { get; set; }
+ //public int isDispatchBlocked { get; set; }
///
/// 状态指示(详见 )
///
- public int stateIndicator { get; set; }
+ //public int stateIndicator { get; set; }
+
+ ///
+ /// 设备参数:Json 格式输出
+ ///
+ public string deviceParamStr{get;set;}
}
\ No newline at end of file
diff --git a/Sln.Wcs.HoistSdk/HoistSdk.cs b/Sln.Wcs.HoistSdk/HoistSdk.cs
index 5b17f77..08e8bce 100644
--- a/Sln.Wcs.HoistSdk/HoistSdk.cs
+++ b/Sln.Wcs.HoistSdk/HoistSdk.cs
@@ -23,23 +23,25 @@
#endregion << 版 本 注 释 >>
+using Newtonsoft.Json;
using Sln.Wcs.HoistSdk.Config;
using Sln.Wcs.HoistSdk.Dto.GetHoistStatus;
using Sln.Wcs.HoistSdk.Dto.HoistControl;
using Sln.Wcs.HoistSdk.Dto.HoistTaskExecutor;
+using Sln.Wcs.Model.Configs;
using Sln.Wcs.Plc.Service;
namespace Sln.Wcs.HoistSdk;
public class HoistSdk:IHoistSdk
{
- private readonly HoistConfig hoistConfig;
+ private readonly HoistConfig _hoistConfig;
private readonly List _plcs;
public HoistSdk(HoistConfig hoistConfig, List plcs)
{
- this.hoistConfig = hoistConfig;
+ _hoistConfig = hoistConfig;
_plcs = plcs;
}
@@ -49,7 +51,7 @@ public class HoistSdk:IHoistSdk
try
{
var plc = _plcs.Where(x => x.ConfigKey.Equals(hoistControlDto.hoistCode)).ToList().First();
- var res = plc.writeInt16ByAddress(hoistConfig.hoist_control_addr, (int)hoistControlDto.action);
+ var res = plc.writeInt16ByAddress(_hoistConfig.hoist_control_addr, (int)hoistControlDto.action);
if (res)
{
result.code = "0";
@@ -76,55 +78,58 @@ public class HoistSdk:IHoistSdk
public GetHoistStatusResultDto GetHoistStatus(GetHoistStatusDto hoistStatusDto)
{
- //一号提升机
- //反馈任务执行指令:是否可以下发任务
- //当前楼层
- //接驳位状态:1-5楼
- //读写器触发状态:1-5楼
- //自动状态:true/1-自动模式
- //屏蔽调度:true/1-屏蔽中
- //状态指示:0-静态;1-上升;2-下降;3-进料;4-出料
-
GetHoistStatusResultDto result = new GetHoistStatusResultDto();
try
{
- var plc = _plcs.Where(x => x.ConfigKey.Equals(hoistStatusDto.hoistCode)).ToList().First();
-
- result.hoistCode = hoistStatusDto.hoistCode;
- result.canDispatchTask = plc.readInt16ByAddress(hoistStatusDto.canDispatchTask);
- result.currentFloor = plc.readInt16ByAddress(hoistStatusDto.currentFloor);
-
- //读取接驳位状态
- List transferStationStatus = new List();
- foreach (var item in hoistStatusDto.transferStationStatus)
+ List paramStr = JsonConvert.DeserializeObject>(_hoistConfig.hoist_plc_param);
+
+ List deviceParams = paramStr.Where(x => x.hostCode == hoistStatusDto.hoistCode).ToList();
+
+ if (string.IsNullOrEmpty(hoistStatusDto.hoistCode))
{
- transferStationStatus.Add(plc.readInt16ByAddress(item));
+ deviceParams = paramStr;
}
- result.transferStationStatus = transferStationStatus.ToArray();
- //读取读写器触发状态
- List readerTriggerStatus = new List();
- foreach (var item in hoistStatusDto.readerTriggerStatus)
+ if (deviceParams != null && deviceParams.Count > 0)
{
- readerTriggerStatus.Add(plc.readInt16ByAddress(item));
+ foreach (var item in deviceParams)
+ {
+
+ if (item.hostCode == hoistStatusDto.hoistCode)
+ {
+ // var plc = _plcs.Where(x => x.ConfigKey.Equals(item.hostCode)).FirstOrDefault();
+ // if (plc == null)
+ // {
+ // result.code = "99";
+ // result.message = $"未找到PLC: {item.hostCode}";
+ // result.hoistCode = hoistStatusDto.hoistCode;
+ // return result;
+ // }
+ //
+ foreach (var param in item.deviceParams)
+ {
+ //int value = plc.readInt16ByAddress(param.paramAddress);
+
+ param.paramValue = param.objId;
+
+ }
+ }
+
+ }
+
+ string jsonOutput = JsonConvert.SerializeObject(deviceParams, Formatting.Indented);
+
+ result.code = "0";
+ result.message = "状态更新成功";
+ result.hoistCode = hoistStatusDto.hoistCode;
+ result.deviceParamStr = jsonOutput;
+ }
+ else
+ {
+ result.code = "99";
+ result.message = $"未获取到设备参数:{hoistStatusDto.hoistCode}";
+ result.hoistCode = hoistStatusDto.hoistCode;
}
- result.readerTriggerStatus = readerTriggerStatus.ToArray();
-
- result.isAutoMode = plc.readInt16ByAddress(hoistStatusDto.isAutoMode);
- result.isDispatchBlocked = plc.readInt16ByAddress(hoistStatusDto.isDispatchBlocked);
- result.stateIndicator = plc.readInt16ByAddress(hoistStatusDto.stateIndicator);
-
- // hoistStatusDto.hoistCode = "";
- // hoistStatusDto.canDispatchTask = "D3101";
- // hoistStatusDto.currentFloor = "D3102";
- // hoistStatusDto.transferStationStatus = new List(){"D3104","D3105","D3106","D3107","D3108"};
- // hoistStatusDto.readerTriggerStatus = new List(){"D3109","D3110","D3111","D3112","D3113"};
- // hoistStatusDto.isAutoMode = "D3124";
- // hoistStatusDto.isDispatchBlocked = "D3125";
- // hoistStatusDto.stateIndicator = "D3127";
-
- result.code = "0";
- result.message = "状态更新成功";
}
catch (Exception e)
{
@@ -133,4 +138,5 @@ public class HoistSdk:IHoistSdk
}
return result;
}
+
}
\ No newline at end of file
diff --git a/Sln.Wcs.Model/Domain/BaseDeviceParam.cs b/Sln.Wcs.Model/Domain/BaseDeviceParam.cs
index 56a6ad6..22037d4 100644
--- a/Sln.Wcs.Model/Domain/BaseDeviceParam.cs
+++ b/Sln.Wcs.Model/Domain/BaseDeviceParam.cs
@@ -80,6 +80,12 @@ public class BaseDeviceParam
[SugarColumn(ColumnName = "param_type")]
public string paramType { get; set; }
+ ///
+ /// 参数值
+ ///
+ [SugarColumn(ColumnName = "param_value")]
+ public int paramValue { get; set; }
+
///
/// Desc:操作类型:1-只读;2-只写;0-默认读写
/// Default:
diff --git a/Sln.Wcs/Program.cs b/Sln.Wcs/Program.cs
index d564359..a400623 100644
--- a/Sln.Wcs/Program.cs
+++ b/Sln.Wcs/Program.cs
@@ -1,8 +1,10 @@
using System.Reflection;
using Com.Ctrip.Framework.Apollo;
using Flurl.Http;
+using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using NeoSmart.Caching.Sqlite;
using Newtonsoft.Json;
@@ -10,22 +12,25 @@ using Sln.Wcs.HikRoBotAdapter.Domain.Dto.GbTaskSubmit;
using Sln.Wcs.HikRoBotAdapter.Domain.Dto.GenAgvSchedulingTask;
using Sln.Wcs.HikRoBotAdapter.Service;
using Sln.Wcs.HikRoBotAdapter.Service.Impl;
+using Sln.Wcs.HoistAdapter.Service;
using Sln.Wcs.HoistSdk;
using Sln.Wcs.HoistSdk.Dto.GetHoistStatus;
using Sln.Wcs.Model.Domain;
using Sln.Wcs.Repository;
+using Sln.Wcs.Repository.service;
using Sln.Wcs.Serilog;
using Sln.Wcs.Plc;
-using Sln.Wcs.Repository.service;
using Sln.Wcs.Strategy;
using ZiggyCreatures.Caching.Fusion;
using ZiggyCreatures.Caching.Fusion.Serialization.NewtonsoftJson;
+using GetHoistStatusDto = Sln.Wcs.HoistAdapter.Domain.Dto.GetHoistStatus.GetHoistStatusDto;
using TargetRoute = Sln.Wcs.HikRoBotAdapter.Domain.Dto.GbTaskSubmit.TargetRoute;
namespace Sln.Wcs
{
public class Program
{
+ private static UpdateableConfigProvider _configProvider;
static async Task Main(string[] args)
{
@@ -41,7 +46,13 @@ namespace Sln.Wcs
log.Info($"系统启动成功,日志存放位置:{config["logPath"]}");
- //禁用 SSL
+ var deviceInfoService = serviceProvider.GetService();
+ List baseDeviceInfos = deviceInfoService.GetDeviceInfos(x => x.isFlag == 1).ToList();
+ string serializeObject = JsonConvert.SerializeObject(baseDeviceInfos);
+ _configProvider.Set("PLC参数", serializeObject);
+ log.Info($"PLC参数已从数据库加载,共{baseDeviceInfos.Count}台设备");
+
+ //禁用 SSL
FlurlHttp.ConfigureClientForUrl("https://172.16.12.11")
.ConfigureInnerHandler(handler =>
{
@@ -59,8 +70,8 @@ namespace Sln.Wcs
// }
// });
- var service = serviceProvider.GetService();
- service.GetHoistStatus(new GetHoistStatusDto());
+ var service = serviceProvider.GetService();
+ service.Run(string.Empty,"tagCode",1,2);
Task.Delay(-1).Wait();
}
@@ -82,6 +93,7 @@ namespace Sln.Wcs
Assembly.LoadFrom(Path.Combine(basePath, "Sln.Wcs.Plc.dll")),
Assembly.LoadFrom(Path.Combine(basePath, "Sln.Wcs.Business.dll")),
Assembly.LoadFrom(Path.Combine(basePath, "Sln.Wcs.Strategy.dll")),
+ Assembly.LoadFrom(Path.Combine(basePath, "Sln.Wcs.HoistDispatcher.dll")),
};
services.Scan(scan => scan.FromAssemblies(assemblies)
@@ -126,11 +138,15 @@ namespace Sln.Wcs
services.AddSingleton(localConfiguration);
+ _configProvider = new UpdateableConfigProvider();
+ _configProvider.Set("PLC参数", "");
+
var configurationBuilder = new ConfigurationBuilder()
.SetBasePath(basePath)
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddApollo(apolloConfigSection)
- .AddDefault();
+ .AddDefault()
+ .Add(_configProvider);
apolloConfiguration = configurationBuilder.Build();
diff --git a/Sln.Wcs/Provider/UpdateableConfigProvider.cs b/Sln.Wcs/Provider/UpdateableConfigProvider.cs
new file mode 100644
index 0000000..388c678
--- /dev/null
+++ b/Sln.Wcs/Provider/UpdateableConfigProvider.cs
@@ -0,0 +1,14 @@
+using Microsoft.Extensions.Configuration;
+
+namespace Sln.Wcs;
+
+internal class UpdateableConfigProvider : ConfigurationProvider, IConfigurationSource
+{
+ public new void Set(string key, string value)
+ {
+ base.Set(key, value);
+ OnReload();
+ }
+
+ public IConfigurationProvider Build(IConfigurationBuilder builder) => this;
+}
diff --git a/Sln.Wcs/Sln.Wcs.csproj b/Sln.Wcs/Sln.Wcs.csproj
index 20d9e80..8eb85be 100644
--- a/Sln.Wcs/Sln.Wcs.csproj
+++ b/Sln.Wcs/Sln.Wcs.csproj
@@ -31,6 +31,7 @@
+