YtSoft.Gmc.Core.Config
1.0.3
dotnet add package YtSoft.Gmc.Core.Config --version 1.0.3
NuGet\Install-Package YtSoft.Gmc.Core.Config -Version 1.0.3
<PackageReference Include="YtSoft.Gmc.Core.Config" Version="1.0.3" />
<PackageVersion Include="YtSoft.Gmc.Core.Config" Version="1.0.3" />
<PackageReference Include="YtSoft.Gmc.Core.Config" />
paket add YtSoft.Gmc.Core.Config --version 1.0.3
#r "nuget: YtSoft.Gmc.Core.Config, 1.0.3"
#:package YtSoft.Gmc.Core.Config@1.0.3
#addin nuget:?package=YtSoft.Gmc.Core.Config&version=1.0.3
#tool nuget:?package=YtSoft.Gmc.Core.Config&version=1.0.3
YtSoft.Gmc.Core.Config 1.0.3
YtSoft.Gmc.Core.Config 1.0.3 是只读配置加载模块。它从进程环境变量取得 Nacos 连接信息和运行环境,在启动时读取共享 namespace 与 DEFAULT_GROUP 中当前环境的 net-*-prod.json 或 net-*-dev.json 文档,将内容绑定为配置对象,并通知已注册的 IOptionsMonitor<T>。模块只负责加载和赋值,不创建数据库连接、网关客户端、中间件客户端或其他运行时实例。
NuGet 接入
本仓库源码版本为 1.0.3。1.0.2 已发布到 NuGet;1.0.3 需要在发布后再从 NuGet 还原。业务系统使用以下包引用;发布前请使用仓库本地打包脚本生成的包源,不需要添加项目引用。
<PackageReference Include="YtSoft.Gmc.Core.Config" Version="1.0.3" />
引用包后即可使用程序集内的 YtSoft.Gmc.Core.Config 类型,无需添加本地项目引用。宿主启动时注册模块:
using YtSoft.Gmc.Core.Config;
var builder = WebApplication.CreateBuilder(args);
await using var runtime = await builder.Services.AddYtSoftConfigAsync(
builder.Configuration,
config => config
.UseLocalFallback("appsettings.json")
.AddOptions<OrdersMiddlewareOptions>());
var app = builder.Build();
await app.RunAsync();
public sealed class OrdersMiddlewareOptions : MiddlewareOptions
{
public bool IsAllow { get; set; }
}
AddYtSoftConfigAsync 返回时已完成远端首载或本地回退、配置注册和首轮绑定。它会注册 IGmcConfigStore、三个基础配置类和所有通过 AddOptions<T> 注册的派生类型。宿主应在 await using 作用域内完成 Build 和运行。
Nacos 环境变量
连接信息和环境选择只从进程环境变量读取,appsettings.json 和 Nacos 文档不能补充或覆盖这些参数。模块读取以下变量:
| 变量 | 必填 | 说明 |
|---|---|---|
NACOS_SERVERS |
是 | 单个 host:port、逗号分隔的地址列表,或 JSON 字符串数组;不带 scheme 时使用 http:// |
NACOS_NAMESPACE |
是 | namespace ID;public 表示公共 namespace |
NACOS_USERNAME |
否 | 与密码同时提供时启用密码认证 |
NACOS_PASSWORD |
否 | 与用户名同时提供时启用密码认证 |
ASPNETCORE_ENVIRONMENT |
否 | Production 选择 net-*-prod.json,Development 选择 net-*-dev.json;缺失或为空按 Production 处理 |
分组固定为 DEFAULT_GROUP,上下文路径固定为 /nacos。三个基础配置类的固定来源为:
| 环境 | Database | Gateway | Middleware |
|---|---|---|---|
| Production | net-database-prod.json |
net-gateway-prod.json |
net-middleware-prod.json |
| Development | net-database-dev.json |
net-gateway-dev.json |
net-middleware-dev.json |
Middleware.MqConnections.QueueNames 是统一日志消费队列名单,使用英文逗号分隔。Middleware.MqConnections.MessageTtl 是日志消息默认过期时间,单位为分钟,缺失时默认 10;零表示消息立即过期,负数由日志生产端按 10 分钟处理。读取到的队列名会去除首尾空白、忽略空项,并按 Ordinal 规则去重;Config 只绑定并发布该配置,不创建 RabbitMQ 客户端。
业务自定义文档使用 net-<业务名称>-prod.json 或 net-<业务名称>-dev.json 命名。模块会加载当前环境下所有匹配文档;其他环境、其他前缀或不符合命名规则的文档不会读取正文、解析、绑定或订阅。扩展名为 .yml/.yaml、DataId 含 -v2- 或 .v2、以及 net-workservice-*.json 的文档已明确排除,不会读取正文、解析、绑定或订阅。三个基础文档由 core 统一选择;独立业务文档的强类型来源按下文显式声明。
环境变量缺失、格式错误、凭据不完整或环境值不受支持时,远端引导失败并尝试本地回退。异常说明只包含排查所需的标识,不包含密码、令牌或配置正文。
连接和环境参数在创建加载器时读取,修改后需要重启宿主;发现间隔为 30 秒,首次加载超时为 60 秒。
内置和自定义配置类
模块默认提供:
DatabaseOptionsGatewayOptionsMiddlewareOptions
业务自定义类型必须继承 DatabaseOptions、GatewayOptions 或 MiddlewareOptions 之一,并通过一次 AddOptions<T>() 注册:
public sealed class OrdersMiddlewareOptions : MiddlewareOptions
{
public bool IsAllow { get; set; }
}
await builder.Services.AddYtSoftConfigAsync(
builder.Configuration,
config => config.AddOptions<OrdersMiddlewareOptions>());
标准 JSON 会按同名属性自动绑定,嵌套对象、数组、字典和业务扩展字段都会递归处理。需要兼容不同键名时,可选使用 ConfigurationKeyNameAttribute:
using Microsoft.Extensions.Configuration;
public sealed class OrdersMiddlewareOptions : MiddlewareOptions
{
[ConfigurationKeyName("Legacy:Allow")]
public bool IsAllow { get; set; }
}
属性名和 JSON 键名一致时不需要特性,也不需要编写字段映射表。特性示例需要宿主使用包含 ConfigurationKeyNameAttribute 的 Microsoft.Extensions 配置包;core 保留 .NET 6 依赖,宿主未提供该特性时可使用 GmcConfigPath 显式声明来源。跨文档或非标准路径也可使用该入口,但标准节内的同名配置应优先自动绑定。
加载独立的自定义配置文档
业务配置有两种使用方式:如果字段属于中间件配置,可以直接把同名字段放进 net-middleware-{suffix}.json,注册继承 MiddlewareOptions 的类型后由标准节自动绑定;如果配置需要独立维护,应建立单独的 net-<业务名称>-{suffix}.json 文档,并为派生配置类显式声明来源。core 会把当前环境下匹配的独立文档加载进快照,但不会把它们无条件合并到 Middleware 节,也不会按 C# 类型名称猜测文档。
下面以 Production 为例。Nacos 中的 net-orders-prod.json 内容是一个简单根对象:
{"IsAllow":true,"RetryCount":3}
定义承载对象和继承 MiddlewareOptions 的外层类型:
public sealed class OrdersSettings
{
public bool IsAllow { get; set; }
public int RetryCount { get; set; }
}
public sealed class OrdersDocumentOptions : MiddlewareOptions
{
public OrdersSettings Orders { get; set; } = new();
}
注册整个 Orders 对象一次即可:
var environmentName = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
var ordersDataId = string.Equals(
environmentName?.Trim(),
"Development",
StringComparison.OrdinalIgnoreCase)
? "net-orders-dev.json"
: "net-orders-prod.json";
await using var runtime = await builder.Services.AddYtSoftConfigAsync(
builder.Configuration,
config => config
.UseLocalFallback("appsettings.json")
.AddOptions<OrdersDocumentOptions>(
GmcConfigPath.FromDocument(ordersDataId, localPath: "Orders"),
nameof(OrdersDocumentOptions.Orders)));
ASPNETCORE_ENVIRONMENT=Development 时,core 会筛选 net-orders-dev.json;Production 或环境变量缺失时使用 net-orders-prod.json。这段代码只声明独立文档到扩展属性的来源,不改变 core 按环境筛选并全量加载匹配文档的规则。FromDocument 的空 path 表示整个 JSON 根对象,新增 OrdersSettings 属性后无需再增加逐字段映射。await 返回时已完成首载和绑定,运行期刷新会自动更新监视器。业务代码保存监视器,每次使用时获取当前对象:
using Microsoft.Extensions.Options;
public sealed class OrdersReader
{
private readonly IOptionsMonitor<OrdersDocumentOptions> _monitor;
public OrdersReader(IOptionsMonitor<OrdersDocumentOptions> monitor)
{
_monitor = monitor;
}
public OrdersSettings Current => _monitor.CurrentValue.Orders;
}
本地回退文件中的 localPath 对应根节点 Orders,同时保留三个标准节:
{
"Database": { "DefaultDatabase": "local-placeholder" },
"Gateway": { "GatewayUrl": "https://127.0.0.1" },
"Middleware": { "IsAllow": false },
"Orders": { "IsAllow": false, "RetryCount": 1 }
}
在远端快照中,可以通过 runtime.GetSnapshot().GetDocument(ordersDataId).GetParsedRoot() 只读检查独立文档;本地回退时按 localPath 读取同一回退文件中的对象。上述注册代码会根据进程环境自动选择对应的文档名,无需添加业务 GmcConfig 或 DataId 配置节。
读取、回退和动态更新
启动时模块先列出目录并校验文档身份,再按当前环境筛选匹配文档;确认正文稳定并完成绑定校验后一次性发布快照。监听信号和定期目录扫描会触发串行全量同步,内容未变化时不会增加 Revision 或重复通知。通过完整校验的文档新增、修改和删除会在下一份快照中体现。
远端首载失败或远端暂时不可用时,模块读取 UseLocalFallback 指定的有效 JSON 文件。远端成功后,运行期失败保留最后一个有效快照,不把远端和本地值混合。业务可注入 IOptionsMonitor<T> 获取当前值:
using Microsoft.Extensions.Options;
public sealed class OrderService
{
public OrderService(
IOptionsMonitor<OrdersMiddlewareOptions> options,
IGmcConfigStore store)
{
var current = options.CurrentValue;
var snapshot = store.GetSnapshot();
}
}
IOptions<T> 和 IOptionsSnapshot<T> 不作为本模块的动态快照入口。未注册类型可以按文档身份读取,但不能直接调用快照绑定方法。
下面的本地回退示例适用于标准节扩展;注册独立 Orders 文档映射时,还需要按上文补充根 Orders 对象:
{
"Database": { "DefaultDatabase": "local-placeholder" },
"Gateway": { "GatewayUrl": "https://127.0.0.1" },
"Middleware": { "IsAllow": false }
}
本地模式不会自动监听文件变化;文件更新后可通过 IGmcConfigStore.RefreshAsync() 显式刷新。远端模式的目录扫描和监听会按模块规则触发全量同步。
IGmcConfigStore.Status 提供 Source、IsStale、Revision、DocumentCount、LastSuccessfulSyncUtc 和安全的 LastError,便于查看当前来源和同步结果。
边界与限制
模块不负责 Nacos 配置发布、服务注册、服务发现或任何运行时客户端初始化。数据库连接池、网关客户端、消息队列客户端等实例由业务系统自行决定和创建。模块只把标准配置节及显式宿主投影写入宿主配置树,未知键不会全部注入宿主配置。
目录响应上限为 8 MiB,最多接受 1000 个文档身份;正文并发上限为 4,远端同步正文总量上限为 64 MiB,本地回退文件上限为 2 MiB。调用方取消会保留旧快照并继续向上传递取消信号。远端和本地来源都无效时,启动才会失败。
旧版迁移
从旧版迁移到 1.0.3 时,将本地项目引用替换为 NuGet YtSoft.Gmc.Core.Config 1.0.3,并使用异步入口:
await services.AddYtSoftConfigAsync(configuration, config =>
config.AddOptions<OrdersMiddlewareOptions>());
从当前源码项目引用切换为同版 NuGet 包,配置加载、快照、回退和监视器行为保持不变。新增的 MqConnections.MessageTtl 只负责绑定默认值,不创建消息队列客户端。更早的同步入口 AddYtSoftConfig、AddYtSoftNacos、服务注册入口 AddYtSoftServiceRegistration 及 YtSoftConfig 静态门面已移除;业务改用上述异步入口,并按 ASPNETCORE_ENVIRONMENT 使用标准文档命名。服务注册和发现由独立组件负责。
验证
库和消费者支持 .NET 6。发布前可先构建本地包源,再验证生产项目:
pwsh -File ./eng/build-local-packages.ps1
dotnet restore YtSoft.Gmc.Core.sln --configfile artifacts/local-packages/NuGet.Config
dotnet build YtSoft.Gmc.Core.sln -c Release --no-restore -p:GeneratePackageOnBuild=false
本地包源用于验证 Config、Contracts、Logging 的依赖版本;配置加载验证可使用本地回退文件或只读的 Nacos 查询,不得向 Nacos 发布、修改或删除配置。测试项目已按项目要求移除。
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net6.0
- Microsoft.Extensions.Configuration (>= 6.0.0)
- Microsoft.Extensions.Configuration.Abstractions (>= 6.0.0)
- Microsoft.Extensions.Configuration.Binder (>= 6.0.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 6.0.0)
- Microsoft.Extensions.Hosting.Abstractions (>= 6.0.0)
- Microsoft.Extensions.Logging.Abstractions (>= 6.0.0)
- Microsoft.Extensions.Options (>= 6.0.0)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 6.0.0)
- YamlDotNet (>= 18.1.0)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on YtSoft.Gmc.Core.Config:
| Package | Downloads |
|---|---|
|
YtSoft.Gmc.Core.Logging
统一日志生产 SDK。业务服务通过 ILogWriter 写入带 tradeId 的日志事件,经 RabbitMQ 投递到日志平台。 |
GitHub repositories
This package is not used by any popular GitHub repositories.