Aore.ConfigManager
1.9.1
dotnet add package Aore.ConfigManager --version 1.9.1
NuGet\Install-Package Aore.ConfigManager -Version 1.9.1
<PackageReference Include="Aore.ConfigManager" Version="1.9.1" />
<PackageVersion Include="Aore.ConfigManager" Version="1.9.1" />
<PackageReference Include="Aore.ConfigManager" />
paket add Aore.ConfigManager --version 1.9.1
#r "nuget: Aore.ConfigManager, 1.9.1"
#:package Aore.ConfigManager@1.9.1
#addin nuget:?package=Aore.ConfigManager&version=1.9.1
#tool nuget:?package=Aore.ConfigManager&version=1.9.1
Aore.ConfigManager — .NET SDK
📈 一个基于 .NET Standard 2.0 的通用配置读取器工具库组件,助力系统和应用取得成功。我将继续保持更新,并正在深度融合更多场景应用👐
使用 Aore.ConfigManager,您可以方便快速将现有项目或新项目实现配置读取支持。
目前 Aore.ConfigManager 支持 .NET Standard 2.0 等多种框架,同时兼容所有 MVC、Razor、WebApi、Console(命令行)、桌面应用(.exe)和后台服务等环境,和外部框架完全解耦。 适用于需要跨平台兼容性的应用程序开发。
希望有更多的人可以从中受益,理解并传播开源的精神,一同助力中国开源事业!感恩一路上给我们提供帮助的朋友们!
如果你喜欢并希望我们继续优化这个项目,请给我们一个 ★Star :)
✨ 功能特性
- 跨框架
- 跨环境
- 可插拔
- 支持数据库
- 高性能
- 完全零外部依赖(AppSettingManager API)/ Newtonsoft.Json 驱动(ConfigHelper API)
- ...
🚀 Aore.ConfigManager 使用示例 :开启你的改造开发之旅!
.NET CLI:
dotnet add package Aore.ConfigManager --version 1.9.1
或
Nuget包进行搜索下载
🛠 AppSettingManager — 流式配置加载器
Web.config or web.xx.config配置文件
// 实例化并指定类型加载器加载全部配置
AppSettingManager manager = new AppSettingManager()
.Add(new AppSettingsXmlProvider("Web.config"))
.Load();
Assert.Equal(12, manager.All.Count);
// ...
web.config / app.config 读取器(XmlDocument),目前仅支持加载:configuration/appSettings/add下的配置项
appsettings*.json or app.json配置文件
// 实例化并指定类型加载器加载全部配置
AppSettingManager manager = new AppSettingManager()
.Add(new JsonConfigProvider("appsettings.json"))
.Load();
Assert.Equal(3, manager.All.Count);
// ...
手写一个 极简递归下降解析器(仅支持 string/number/bool/null/object/array),满足 appsettings*.json 的 key-value 扁平化需求
DatabaseConfig数据库读取器
// 实例化并指定类型加载器加载全部配置
// 首先项目要提供连接数据的驱动依赖(System.Data.SQLite)
// SQL指定返回两列(第一列为Key,第二列为Value)
AppSettingManager manager = new AppSettingManager()
.Add(new DatabaseConfigProvider("System.Data.SQLite", "Data Source=AppConfig.db;Version=3;", "SELECT [Key],[Value] FROM config"))
.Load();
Assert.Equal(2, manager.All.Count);
// ...
项目要有对应驱动(System.Data.SqlClient / Microsoft.Data.SqlClient / MySql.Data 等)即可,无需编译期引用
获取配置值的方法API
Assert.Equal("localhost", manager["Host"]);
Assert.Equal("localhost", manager.All["Host"]);
// Test GetConfig<T>
Assert.Equal("localhost", manager.GetConfig<string>("Host"));
Assert.Equal(443, manager.GetConfig<int>("Port"));
// Test GetConfig(string key, string defaultValue = "")
Assert.Equal("localhost", manager.GetConfig("ERP_URL", "localhost"));
// Test GetTryConfig
string? sERPUrl;
Assert.Equal(false, manager.GetTryConfig("ERP_URL", out sERPUrl));
// Test GetTryConfig DefaultValue
Assert.Equal(true, manager.GetTryConfig("ERP_URL", "loaclhost", out sERPUrl));
Assert.Equal("loaclhost", sERPUrl);
// ...
字典类型的配置转换成指定类型
(字典Key ⇒ 对象中的字段)
AppSettingManager manager = new AppSettingManager()
.Add(new AppSettingsXmlProvider("Web.config"))
.Load();
WebConfigModel model = manager.ConvertTo<WebConfigModel>();
Assert.Equal("localhost", model.Host);
// 配置对象
class WebConfigModel
{
public string? Host { get; set; }
public int Port { get; set; }
}
// ...
// appsetting.json => Object(嵌套映射 - 推荐)
// json的key是Logging:Debug:LogLevel:Default,自动映射到嵌套属性 Logging.Debug.LogLevel.Default
AppSettingManager manager = new AppSettingManager()
.Add(new JsonConfigProvider("appsettings.json"))
.Load();
LoggingModel model = manager.ConvertTo<LoggingModel>();
Assert.Equal("Warning", model.Logging!.Debug!.LogLevel!.Default);
// 配置对象(嵌套结构,与JSON层级对应)
class LoggingModel
{
public LoggingSection? Logging { get; set; }
}
class LoggingSection
{
public bool IncludeScopes { get; set; }
public DebugSection? Debug { get; set; }
}
class DebugSection
{
public LogLevelSection? LogLevel { get; set; }
}
class LogLevelSection
{
public string? Default { get; set; }
public string? System { get; set; }
}
// 也支持旧的下划线命名方式(向后兼容)
// json的key是Logging:Debug:LogLevel:Default,对应属性名 Logging_Debug_LogLevel_Default
FlatLoggingModel flatModel = manager.ConvertTo<FlatLoggingModel>();
Assert.Equal("Warning", flatModel.Logging_Debug_LogLevel_Default);
class FlatLoggingModel
{
public string? Logging_Debug_LogLevel_Default { get; set; }
}
🏗️ ConfigHelper<T> — 属性驱动配置管理
ConfigHelper<T> 提供属性驱动的配置管理,支持 JSON/XML 格式、热重载、线程安全读写。
核心概念
一句话:给实体类加特性,自动生成带注释的 JSON/XML 配置文件,双向映射零代码。
你的 C# 类 配置文件
┌─────────────────┐ ┌──────────────────────┐
│ [JsonConfig("app.json")] │ { │
│ public class AppConfig │ // 设备IP │
│ { │ "deviceIp": "10...",│
│ [Config(Desc="设备IP")] │ "port": 502 │
│ public string Ip {get;set;}│ } │
│ } └──────────────────────┘
└─────────────────┘
↓ ConfigFactory.Load<T>()
↑ ConfigFactory.Save(cfg)
支持的配置格式:JSON(带 // 注释,JSONC兼容)/ XML(带 ``)
10分钟完整教程
Step 1 — 定义实体类,加两个特性
using Aore.ConfigManager;
using System.Collections.Generic;
// 类上加 [JsonConfig] 或 [XmlConfig] — 指定文件路径
[JsonConfig("config/laser.json")]
public class LaserConfig
{
// 属性上统一用 [Config(...)] 8个参数按需组合
[Config(Desc = "设备IP地址", Default = "192.168.1.100", StringLength = 15, Required = true)]
public string DeviceIp { get; set; } = string.Empty;
[Config(Desc = "Modbus端口", Default = 502)]
public int DevicePort { get; set; }
[Config(Desc = "曝光时间(微秒)", Default = 5000)]
public int ExposureTimeUs { get; set; }
[Config(Desc = "相机列表")] // List 不能设 Default,会自动 new()
public List<CameraInfo> Cameras { get; set; } = null!;
[Config(Desc = "校准参数")] // 嵌套对象自动展开子属性
public CalibrationParams Calibration { get; set; } = new();
[Config(Desc = "是否启用", Converter = typeof(BoolFormatConverter),
ConverterArgs = new object[] { "是", "否" })]
public bool Enabled { get; set; } = true;
[Config(Ignore = true)] // 运行时状态,不写文件
public bool IsConnected { get; set; }
}
public class CameraInfo
{
[Config(Desc = "相机名称", Default = "Camera-001")]
public string Name { get; set; } = string.Empty;
[Config(Desc = "序列号")]
public string SerialNumber { get; set; } = string.Empty;
}
public class CalibrationParams
{
[Config(Desc = "X偏移", Default = 0.0)]
public double OffsetX { get; set; }
[Config(Desc = "Y偏移", Default = 0.0)]
public double OffsetY { get; set; }
}
Step 2 — 程序入口初始化
// 一行加载(文件不存在 → 自动创建带默认值的配置文件)
var cfg = ConfigFactory.Load<LaserConfig>();
Console.WriteLine(cfg.DeviceIp); // "192.168.1.100"
// 修改
cfg.DeviceIp = "10.0.0.1";
cfg.Cameras.Add(new CameraInfo { Name = "Camera-001", SerialNumber = "SN001" });
// 一行保存
ConfigFactory.Save(cfg);
Step 3 — 查看生成的 config/laser.json
{
// 设备IP地址
// [默认值: 192.168.1.100] [最大长度: 15]
"deviceIp": "10.0.0.1",
// Modbus端口
// [默认值: 502]
"devicePort": 502,
// 曝光时间(微秒)
// [默认值: 5000]
"exposureTimeUs": 5000,
// 相机列表
"cameras": [
{
// 相机名称
// [默认值: Camera-001]
"name": "Camera-001",
// 序列号
"serialNumber": "SN001"
}
],
// 校准参数
"calibration": {
// X偏移
// [默认值: 0]
"offsetX": 0,
// Y偏移
// [默认值: 0]
"offsetY": 0
},
// 是否启用
"enabled": "是"
}
注释即文档。 别人打开 JSON,不用查代码也知道每个字段是干嘛的。
[Config] 8 个参数详解
| # | 参数 | 类型 | 默认 | 说明 |
|---|---|---|---|---|
| 1 | Desc |
string? |
null |
属性描述 → 生成 // 注释(JSON)或 ``(XML) |
| 2 | Key |
string? |
null |
自定义 JSON/Xml 键名。默认根据 NamingPolicy 自动转换 |
| 3 | Default |
object? |
null |
默认值。仅基础类型生效(string/int/double/bool/DateTime/Enum),class/List 报错 |
| 4 | Ignore |
bool |
false |
true → 序列化和反序列化都跳过。与 Required 互斥 |
| 5 | Required |
bool |
false |
true → 加载时值为 null 或空字符串抛 ConfigValidationException。与 Ignore 互斥 |
| 6 | StringLength |
int |
0 |
字符串最大长度。>0 生效,仅 string 有效,非 string 报错 |
| 7 | Converter |
Type? |
null |
自定义转换器类型,必须实现 IConfigConverter |
| 8 | ConverterArgs |
object?[]? |
null |
传给转换器构造函数的参数。必须配合 Converter,单独用报错 |
运行时校验(写错即报)
| 错误写法 | 报错信息 |
|---|---|
[Config(Ignore=true, Required=true)] |
Ignore 和 Required 不能同时为 true |
[Config(StringLength=10)] int Port |
StringLength 仅适用于 string 类型 |
[Config(Default="abc")] List<T> x |
复杂类型/集合类型不能设置 Default 值 |
[Config(Default="abc")] int x |
Default 值类型无法转换为目标类型 |
[Config(Converter=typeof(Xxx))] 未实现接口 |
Converter 类型必须实现 IConfigConverter |
[Config(ConverterArgs=new[]{"a"})] 无 Converter |
ConverterArgs 必须配合 Converter 一起使用 |
两个类级特性
[JsonConfig]
[JsonConfig("config/app.json")] // 路径(必填)
public class AppConfig { }
[XmlConfig]
[XmlConfig("config/app.xml", RootName = "AppSettings")] // RootName 可选,默认用类名
public class AppSettings { }
生成的 XML:
<?xml version="1.0" encoding="utf-8"?>
<AppSettings>
<CompanyName>MyCompany</CompanyName>
</AppSettings>
XML 格式推荐同时加
[XmlRoot]/[XmlElement]获得最佳兼容性。内部XmlConfigHelper.CreateSerializer<T>()已自动适配[Config(Key="...")]。
ConfigFactory — 零代码入口
// ═══ 加载 ═══
var cfg = ConfigFactory.Load<LaserConfig>();
// 行为:
// 首次调用 → 反射读取 [JsonConfig] → 创建 ConfigHelper 并缓存
// 文件不存在 → new T() + [Config(Default=...)] → 写入文件
// 文件存在 → 反序列化 + 应用默认值 + 补 null → 触发 ConfigChanged(Initial)
// 后续调用 → 返回缓存的 ConfigHelper.Value
// ═══ 保存 ═══
ConfigFactory.Save(cfg);
// 通过缓存的 ConfigHelper.Save() 写回文件
// ═══ 生成(写文件但不加载到内存) ═══
ConfigFactory.Generate<LaserConfig>();
// ═══ 获取 ConfigHelper(注册事件等) ═══
var helper = ConfigFactory.GetHelper<LaserConfig>();
if (helper != null)
{
helper.ConfigChanged += (_, e) => Console.WriteLine("配置已变更");
helper.EnableHotReload();
}
// ═══ 手动注册(自定义路径/格式) ═══
var h = ConfigFactory.Register<LaserConfig>("other/path.json", ConfigFormat.Json);
ConfigHelper<T> 完整 API
构造函数
var helper = new ConfigHelper<LaserConfig>(
"config/laser.json", // 文件路径
ConfigFormat.Json, // Json 或 Xml
jsonSettings: null, // 自定义 JsonSerializerSettings
autoLoad: true // 是否自动 Load()
);
属性
| 属性 | 类型 | 说明 |
|---|---|---|
.Value |
T |
获取当前配置实例(线程安全,ReaderWriterLockSlim 保护) |
.FilePath |
string |
配置文件完整路径 |
.FileExists |
bool |
文件是否存在 |
.LastError |
Exception? |
最近一次 Load/Save 的错误(TryLoad 失败后查看) |
.Properties |
IReadOnlyList<PropMeta> |
所有属性的元数据快照 |
方法
| 方法 | 返回 | 说明 |
|---|---|---|
.Load() |
T |
从文件加载(文件不存在→自动创建) |
.Reload() |
T |
强制从文件重新加载,忽略缓存 |
.TryLoad(out T) |
bool |
安全加载,失败返回 false,错误→.LastError |
.TryReload(out T) |
bool |
安全重载 |
.Save() |
void |
原子保存(先写 .tmp,再 File.Move 覆盖原文件) |
.SaveCopy(T) |
void |
保存指定对象到文件,不替换当前 .Value |
.EnableHotReload() |
void |
FileSystemWatcher 监听文件变更,自动 Reload |
.DisableHotReload() |
void |
关闭热重载 |
.GetSnapshot() |
T |
深拷贝当前配置(JSON序列化→反序列化) |
.Update(Action<T>) |
void |
原子修改(锁内执行 lambda,无需手动加锁) |
.GetPropertyValue(name) |
object? |
通过反射获取单个属性值 |
.SetPropertyValue(name, value) |
void |
通过反射设置单个属性值 |
.ImportFromJson(json) |
void |
从 JSON 字符串反序列化导入 |
.ExportToJson(indented) |
string |
序列化为 JSON 字符串 |
.Dispose() |
void |
释放 FileSystemWatcher + 读写锁 |
事件
| 事件 | 触发时机 | 参数 |
|---|---|---|
ConfigChanged |
Load/Reload/Save 成功后 | ConfigChangedEventArgs<T> : OldConfig, NewConfig, ChangeType |
ConfigSaving |
Save 被调用时(可取消) | ConfigSavingEventArgs<T> : Config, Cancel |
ChangeType 枚举:Initial(首次加载)、Saved(Save 后)、HotReload(FileSystemWatcher 触发)、Reloaded(手动 Reload)
PropMeta
通过 helper.Properties 获取:
| 字段 | 说明 |
|---|---|
Property |
PropertyInfo 反射对象 |
JsonKey |
JSON 序列化键名 |
XmlElementName |
XML 元素名 |
HasConfigDefault |
是否通过 [Config(Default=...)] 设置了默认值 |
ConfigDefaultValue |
注解默认值 |
IsRequired |
[Config(Required=true)] |
MaxStringLength |
[Config(StringLength=...)] |
Description |
[Config(Desc="...")] |
ConverterType |
[Config(Converter=typeof(...))] |
ConverterArgs |
[Config(ConverterArgs=...)] |
CanWrite |
属性是否有 setter |
热重载(EnableHotReload / DisableHotReload)
var helper = ConfigFactory.GetHelper<LaserConfig>();
helper.EnableHotReload(); // ← 调用后生效
helper.ConfigChanged += (sender, e) =>
{
// e.ChangeType == ChangeType.HotReload → 文件被外部修改
// e.ChangeType == ChangeType.Saved → 程序 Save()
// e.ChangeType == ChangeType.Reloaded → 手动 Reload()
// e.ChangeType == ChangeType.Initial → 首次 Load()
Console.WriteLine($"IP 变更: {e.OldConfig?.DeviceIp} → {e.NewConfig.DeviceIp}");
// 无需加锁,直接读取 e.NewConfig
UpdateUI(e.NewConfig);
};
| 问题 | 答案 |
|---|---|
| 实现原理 | FileSystemWatcher 监听 LastWrite 和 Changed |
| 防抖时间 | 100ms,避免编辑器保存时多次触发 |
| 安全性 | OnFileChanged 捕获所有异常,不影响主线程 |
| 何时不触发 | 程序内部 Save() 走保存路径,不走热重载路径 |
| 如何关闭 | DisableHotReload() |
GetSnapshot 快照
场景1 — 修改前备份,改坏了回滚
var backup = helper.GetSnapshot();
try
{
helper.Update(cfg => { cfg.DevicePort = 99999; });
helper.Save();
}
catch
{
// 回滚
helper.Update(cfg => { cfg.DevicePort = backup.DevicePort; });
}
场景2 — diff 新旧配置
var old = helper.GetSnapshot();
helper.Reload();
var @new = helper.Value;
if (old.DeviceIp != @new.DeviceIp) Log("配置变更", old, @new);
场景3 — 多模块各拿独立拷贝
var module1Cfg = helper.GetSnapshot(); module1Cfg.Port = 502;
var module2Cfg = helper.GetSnapshot(); module2Cfg.Port = 8080;
// module1Cfg 和 module2Cfg 互不影响,也不影响 helper.Value
快照通过 JSON 序列化+反序列化实现深拷贝,性能开销约等于一次完整序列化。
属性默认值处理规则
反序列化后每个属性的处理:
┌──────────────────────────────────────────────┐
│ 属性值 != null ? │
│ ├─ Yes → 保持原值 │
│ └─ No → 是什么类型? │
│ ├─ 值类型 (int,double,bool...) │
│ │ → 赋 C# default (0, 0.0, false)│
│ ├─ string │
│ │ → 赋 ""(空字符串非null) │
│ ├─ List<T> / IList 等集合 │
│ │ → 赋 new List<T>() │
│ └─ 其他 class │
│ → 保持 null(让用户手动new) │
│ │
│ 然后再检查 [Config(Default=xxx)]: │
│ 如果当前值 == C#默认值 → 应用注解默认值 │
└──────────────────────────────────────────────┘
内置转换器
| # | 类型 | 示例 | 构造参数 |
|---|---|---|---|
| 1 | HexIntConverter |
255 ↔ "0xFF" |
无 |
| 2 | TimeSpanStringConverter |
TimeSpan(1,30,0) ↔ "01:30:00" |
无 |
| 3 | DateTimeStringConverter |
2026-06-16 14:00:00 ↔ "2026-06-16 14:00:00" |
无 |
| 4 | BoolFormatConverter |
true ↔ "是" |
trueText(默认"1"), falseText(默认"0") |
| 5 | NumberFormatConverter |
3.14159 ↔ "3.14" |
format(默认"F2") |
| 6 | VersionConverter |
Version(2,1,0) ↔ "2.1.0" |
无 |
| 7 | TypeNameConverter |
typeof(MyClass) ↔ "Namespace.MyClass, Assembly" |
无 |
| 8 | EnumIntConverter |
MyEnum.Value3 ↔ "3" |
无 |
有参转换器的使用
// BoolFormatConverter(trueText, falseText)
[Config(Converter = typeof(BoolFormatConverter),
ConverterArgs = new object[] { "是", "否" })]
public bool Enabled { get; set; }
// NumberFormatConverter(format)
[Config(Converter = typeof(NumberFormatConverter),
ConverterArgs = new object[] { "F3" })]
public double Precision { get; set; }
自定义转换器
public class MyHexConverter : IConfigConverter
{
// 实体 → 配置字符串(序列化时调用)
public string ConvertTo(object? value)
{
if (value is int v) return $"0x{v:X4}";
return "0x0000";
}
// 配置字符串 → 实体(反序列化时调用)
public object? ConvertFrom(string? configValue)
{
if (string.IsNullOrEmpty(configValue)) return 0;
return Convert.ToInt32(configValue.Replace("0x", ""), 16);
}
}
[Config(Converter = typeof(MyHexConverter))]
public int Address { get; set; }
核心安全机制
| 机制 | 实现 |
|---|---|
| 原子保存 | 先写 .tmp 临时文件,再 File.Move 覆盖。写一半崩溃不损坏原文件 |
| 损坏容错 | JSON 反序列化失败 → 原文件备份为 .corrupted_时间戳 → 创建默认配置 |
| 线程安全 | ReaderWriterLockSlim,读读不互斥、读写互斥、写写互斥 |
| 事件异步 | ConfigChanged 通过 ThreadPool.QueueUserWorkItem 触发,锁内不执行用户代码 |
| TryLoad | 失败不抛异常,通过 LastError 获取 |
| 运行时校验 | 错误特性组合在首次 BuildPropMetaCache 时即报错 |
完整 API 速查表
// ═══ 零代码(推荐) ═══
ConfigFactory.Load<T>() // 加载配置
ConfigFactory.Save(config) // 保存配置
ConfigFactory.Generate<T>() // 仅生成文件
ConfigFactory.GetHelper<T>() // 获取 ConfigHelper 实例(注册事件等)
ConfigFactory.Register<T>(path, format) // 手动注册
// ═══ 加载/保存 ═══
new ConfigHelper<T>(path, format, jsonSettings, autoLoad)
helper.Load() / helper.Reload()
helper.TryLoad(out) / helper.TryReload(out)
helper.Save() / helper.SaveCopy(config)
// ═══ 数据操作 ═══
helper.Value // 获取配置(线程安全)
helper.Update(cfg => {}) // 原子修改(锁内 Lambda)
helper.GetSnapshot() // 深拷贝(JSON序列化/反序列化)
helper.GetPropertyValue("name")
helper.SetPropertyValue("name", value)
helper.ImportFromJson(jsonString)
helper.ExportToJson(indented)
// ═══ 事件/热重载 ═══
helper.ConfigChanged += (s, e) => { }
helper.ConfigSaving += (s, e) => { e.Cancel = true; } // 取消保存
helper.EnableHotReload() / helper.DisableHotReload()
// ═══ 扩展方法 ═══
config.EnsureListsInitialized() // 初始化所有 List 属性
config.EnsureDefaultsForNulls() // 为 null 属性填充默认值
ConfigManager — 全局注册(兼容旧版)
// 注册并获取配置
var cfg = ConfigManager.Register<AppConfig>("config/app.json");
// 获取已注册的配置
var cfg2 = ConfigManager.Get<AppConfig>();
// 获取 ConfigHelper 实例
var helper = ConfigManager.GetHelper<AppConfig>();
// 注销
ConfigManager.Unregister<AppConfig>();
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. 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 is compatible. 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. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 is compatible. net48 is compatible. net481 is compatible. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETFramework 4.7.2
- Newtonsoft.Json (>= 13.0.3)
-
.NETFramework 4.8
- Newtonsoft.Json (>= 13.0.3)
-
.NETFramework 4.8.1
- Newtonsoft.Json (>= 13.0.3)
-
.NETStandard 2.0
- Newtonsoft.Json (>= 13.0.3)
-
net6.0
- Newtonsoft.Json (>= 13.0.3)
-
net8.0
- Newtonsoft.Json (>= 13.0.3)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Aore.ConfigManager is a universal configuration reader that is cross framework, cross environment, pluggable, and supports databases component for .NET