跳到主要内容
版本:3.0.0

配置(Aegis.Configuration)

当你需要在 Aegis 3.x 中统一读取 appsettings.json、自定义 JSON 配置、类型化配置对象,并让业务代码和组件都通过 ConfigManager 访问配置时,可以使用 Aegis.Configuration。它是很多组件的共同底座,也是 Aegis 运行时中的默认配置能力。

组件概览

字段说明
组件名称配置
真实类库Aegis.Configuration
组件定位提供统一配置读取入口、类型绑定能力和额外 JSON 配置加载能力
子级扩展Aegis.Configuration.ConfigCenter
引入方式Aegis 运行时默认接入
核心能力ConfigManagerConfigRootLoadConfigurations、配置数组读取
是否可扩展
注册入口AddConfiguration
中间件阶段

这个组件更像配置底座,而不是一个需要你单独声明的业务组件。正常使用 Aegis 时,它已经在运行时初始化阶段接好,因此文档重点不在“怎么单独注册它”,而在“它提供了哪些配置能力、应该怎么使用”。

如何引入

NuGet 包

角色NuGet 包是否必需说明
基础层Aegis.Configuration提供统一配置读取能力
扩展层Aegis.Configuration.ConfigCenter按需用于接入远端配置中心

接入方式

Aegis.Configuration 不通过 Component.deps.json 引入。它属于 Aegis 默认运行时能力,正常使用时不需要再为它额外补一段单独注册代码。

配置说明

这个组件本身没有强制的独立配置节点,但最常见的是 LoadConfigurations

节点类型是否必填说明常见取值 / 示例
LoadConfigurationsstring[]追加加载自定义 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_ENVIRONMENTDOTNET_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 应该写目录还是文件?

默认推荐目录。目录方式更适合团队协作、增量扩展和长期维护;如果你确实需要单文件路径,建议把它当作按需方案,并在启动后验证目标配置节点是否已经可读。