配置(Aegis.Configuration)
当你需要在 Aegis 3.x 中统一读取 appsettings.json、自定义 JSON 配置、类型化配置对象,并让业务代码和组件都通过 ConfigManager 访问配置时,可以使用 Aegis.Configuration。它是很多组件的共同底座,也是 Aegis 运行时中的默认配置能力。
组件概览
| 字段 | 说明 |
|---|---|
| 组件名称 | 配置 |
| 真实类库 | Aegis.Configuration |
| 组件定位 | 提供统一配置读取入口、类型绑定能力和额外 JSON 配置加载能力 |
| 子级扩展 | Aegis.Configuration.ConfigCenter |
| 引入方式 | Aegis 运行时默认接入 |
| 核心能力 | ConfigManager、ConfigRoot、LoadConfigurations、配置数组读取 |
| 是否可扩展 | 是 |
| 注册入口 | AddConfiguration |
| 中间件阶段 | 无 |
这个组件更像配置底座,而不是一个需要你单独声明的业务组件。正常使用 Aegis 时,它已经在运行时初始化阶段接好,因此文档重点不在“怎么单独注册它”,而在“它提供了哪些配置能力、应该怎么使用”。
如何引入
NuGet 包
| 角色 | NuGet 包 | 是否必需 | 说明 |
|---|---|---|---|
| 基础层 | Aegis.Configuration | 是 | 提供统一配置读取能力 |
| 扩展层 | Aegis.Configuration.ConfigCenter | 按需 | 用于接入远端配置中心 |
接入方式
Aegis.Configuration 不通过 Component.deps.json 引入。它属于 Aegis 默认运行时能力,正常使用时不需要再为它额外补一段单独注册代码。
配置说明
这个组件本身没有强制的独立配置节点,但最常见的是 LoadConfigurations:
| 节点 | 类型 | 是否必填 | 说明 | 常见取值 / 示例 |
|---|---|---|---|---|
LoadConfigurations | string[] | 否 | 追加加载自定义 JSON 配置目录或文件 | ["Configs/"] |
最小示例:
{
"LoadConfigurations": [
"Configs/"
]
}
推荐做法是优先写目录路径,让程序自动扫描目录下的 *.json 文件。这样在后续扩配置时更稳,也更便于长期维护。
快速使用
第一步:准备主配置和额外配置
appsettings.json
{
"LoadConfigurations": [
"Configs/"
],
"RedisUrl": "127.0.0.1:6379",
"MaxNumber": 99
}
Configs/Medical.json
{
"MedicalOption": {
"Host": "https://example.com",
"Port": 8001
}
}
第二步:定义类型化配置类
using Aegis.Configuration.Attributes;
[ConfigRoot("MedicalOption")]
public class MedicalConfig
{
public string Host { get; set; }
public int Port { get; set; }
}
第三步:在业务代码里读取配置
var redisUrl = ConfigManager.Get("RedisUrl");
var maxNumber = ConfigManager.Get<int>("MaxNumber");
var medicalConfig = ConfigManager.Get<MedicalConfig>();
var loadConfigurations = ConfigManager.GetArray<string>("LoadConfigurations");
接入正确时,你应该能看到这些结果:
ConfigManager.Get("RedisUrl")可以读取普通字符串配置。ConfigManager.Get<MedicalConfig>()可以拿到绑定后的对象。ConfigManager.GetArray<string>("LoadConfigurations")可以读取数组配置。- 追加目录中的 JSON 配置会并入统一配置树。
具体使用详情
统一配置读取方式
ConfigManager 当前提供四类常用读取方式:
Get(string key):读取字符串值Get<T>(string key):读取指定节点并绑定为类型Get<T>():按类型名或ConfigRoot自动匹配节点GetArray<T>(string key):读取数组配置
如果你希望团队对配置读取方式保持一致,推荐默认使用 ConfigManager,而不是在业务代码里混用多套读取方式。
下面是最常见的读取示例:
var sqlConnection = ConfigManager.Get("SqlConnection");
var workerId = ConfigManager.Get<int>("IdGenerator:WorkerId");
var swaggerOptions = ConfigManager.Get<SwaggerOptions>("Swagger");
var databases = ConfigManager.GetArray<DatabaseConfig>("Databases");
public class DatabaseConfig
{
public string ConnectionName { get; set; }
public string DatabaseType { get; set; }
public string ConnectionString { get; set; }
}
类型绑定与 ConfigRoot
当配置类上声明了 ConfigRoot 时,ConfigManager.Get<T>() 会优先按该节点名读取配置。没有声明时,会默认使用类型名作为节点名。
适合场景:
- 配置节点名和类名不一致
- 希望把配置节点映射规则显式写在模型上
- 想让业务代码直接使用
Get<T>()
using Aegis.Configuration.Attributes;
[ConfigRoot("MedicalOption")]
public class MedicalConfig
{
public string Host { get; set; }
public int Port { get; set; }
}
var medicalConfig = ConfigManager.Get<MedicalConfig>();
var medicalConfigByKey = ConfigManager.Get<MedicalConfig>("MedicalOption");
Console.WriteLine(medicalConfig.Host);
Console.WriteLine(medicalConfig.Port);
自定义 JSON 配置加载
LoadConfigurations 用于把程序目录中的额外配置并入统一配置树。比较适合:
- 业务模块较多,希望把配置拆分到独立目录
- 需要把公共配置和业务配置分开维护
- 不希望所有配置都堆在同一个
appsettings.json中
使用时的约束:
- 路径应相对程序运行目录组织
- 长期维护建议优先使用目录
- 如果你采用单文件路径,请在启动后确认目标节点已经可以被正确读取
{
"LoadConfigurations": [
"Configs/",
"BizConfigs/BizConfig.json"
]
}
var loadConfigurations = ConfigManager.GetArray<string>("LoadConfigurations");
foreach (var path in loadConfigurations)
{
Console.WriteLine(path);
}
按环境加载不同配置文件
LoadConfigurations 中的路径支持 {Environment} 占位符,运行时会自动替换为当前环境名称(与 appsettings.{Environment}.json 的环境判断逻辑一致:依次读取 ASPNETCORE_ENVIRONMENT、DOTNET_ENVIRONMENT 环境变量,默认为 Production)。
两种常见用法:
按文件名区分:
{
"LoadConfigurations": [
"Configs/",
"BizConfigs/BizConfig{Environment}.json"
]
}
当 ASPNETCORE_ENVIRONMENT=Development 时,BizConfigs/BizConfig{Environment}.json 会被解析为 BizConfigs/BizConfigDevelopment.json。
按目录区分:
{
"LoadConfigurations": [
"Configs/{Environment}/"
]
}
目录方式会在运行时解析为 Configs/Development/、Configs/Production/ 等,框架自动扫描对应目录下所有 *.json 文件。文件结构可以这样组织:
Configs/
├── Development/
│ ├── BizConfig.json
│ └── ExternalApi.json
├── Production/
│ ├── BizConfig.json
│ └── ExternalApi.json
按目录区分比在文件名中嵌入环境名更清晰,适合配置文件较多的场景。
文件或目录不存在时不会报错,该路径会被跳过。
对其他组件的意义
很多组件在注册服务时会直接读取配置,因此 Aegis.Configuration 实际上是大量组件的前置底座。例如:
- Redis 组件读取
Redis - 认证组件读取
Auth - 任务调度组件读取连接串和服务器标识
也正因为如此,配置初始化越早完成越稳。
var redisOptions = ConfigManager.Get<RedisOptions>("Redis");
var authEnabled = ConfigManager.Get<bool>("Auth:EnableAuthentication");
var serverId = ConfigManager.Get("ServerSettings:ServerId");
如何扩展
接入远端配置中心
如果本地 JSON 配置已经不够用,可以在此基础上叠加:
这样业务层仍然通过 ConfigManager 读取配置,不需要切换成另一套 API。
扩展配置模型
长期维护时,推荐为稳定的业务配置建立独立类型,并用 ConfigRoot 标注节点名称。这样比在代码里散落字符串键名更易维护。
[ConfigRoot("FileStorage")]
public class FileStorageOptions
{
public string RootPath { get; set; }
public string Provider { get; set; }
}
var fileStorage = ConfigManager.Get<FileStorageOptions>();
常见问题指南
为什么 ConfigManager.Get(...) 会直接报错?
通常说明当前运行环境中的配置初始化没有按 Aegis 默认链路完成,或者读取时机早于配置可用时机。排查时优先确认应用是否按标准方式启动,以及当前配置节点本身是否存在。
这个组件为什么没有写进 Component.deps.json?
因为它不是按组件声明驱动的业务扩展,而是 Aegis 默认运行时中的基础配置能力。把它写进 Component.deps.json 不是当前推荐用法。
LoadConfigurations 应该写目录还是文件?
默认推荐目录。目录方式更适合团队协作、增量扩展和长期维护;如果你确实需要单文件路径,建议把它当作按需方案,并在启动后验证目标配置节点是否已经可读。