# 配置项 (Options)

最后更新: 2024-09-20


# 📚 概述

DarkM 框架采用 .NET Core 的配置系统,支持多种配置源(JSON、环境变量、命令行等),并提供强类型的选项模式。


# 🎯 配置结构

# 默认配置文件

WebHost/
├── appsettings.json              # 基础配置(生产环境)
├── appsettings.Development.json  # 开发环境配置
└── appsettings.Production.json   # 生产环境配置(可选)
1
2
3
4

# 配置分层

{
  "Host": {
    "Urls": "http://*:6220",
    "Swagger": true
  },
  "Db": {
    "Dialect": 2,
    "Server": "../../data/SQLite",
    "Modules": [
      {
        "Name": "Admin",
        "Database": "Nm_Admin"
      }
    ]
  },
  "Cache": {
    "Provider": 0,
    "Redis": {
      "ConnectionString": "127.0.0.1:6379"
    }
  },
  "Serilog": {
    "MinimumLevel": "Information"
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

# 🔧 配置项说明

# 1. 主机配置 (Host)

{
  "Host": {
    "Urls": "http://*:6220",        // 监听地址和端口
    "Swagger": true,                 // 是否开启 Swagger
    "Proxy": false,                  // 是否启用代理
    "PreflightMaxAge": 1800          // 跨域预检请求有效期(秒)
  }
}
1
2
3
4
5
6
7
8
配置项 类型 默认值 说明
Urls string http://*:6220 应用监听地址
Swagger bool true 是否启用 Swagger UI
Proxy bool false 是否启用反向代理
PreflightMaxAge int 1800 CORS 预检请求缓存时间

# 2. 数据库配置 (Db)

{
  "Db": {
    "Logging": false,                // 是否记录 SQL 日志
    "Dialect": 2,                    // 数据库类型
    "Server": "../../data/SQLite",   // 数据库地址
    "Port": 0,                       // 端口号
    "UserId": "",                    // 用户名
    "Password": "",                  // 密码
    "CreateDatabase": true,          // 自动创建数据库和表
    "InitData": true,                // 自动初始化数据
    "Modules": [                     // 模块列表
      {
        "Name": "Admin",
        "Database": "Nm_Admin",
        "Prefix": "",
        "ConnectionString": ""
      }
    ]
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# Dialect 枚举值

数据库 示例
0 SqlServer Server=192.168.1.100;Database=DarkM;
1 MySql Server=127.0.0.1;Port=3306;
2 SQLite ../../data/SQLite
3 PostgreSQL Server=127.0.0.1;Port=5432;

# 模块配置

配置项 说明 示例
Name 模块名称 Admin
Database 数据库名称 Nm_Admin
Prefix 表前缀 T_
ConnectionString 自定义连接字符串(可选) 为空则使用 Db.Server

# 3. 缓存配置 (Cache)

{
  "Cache": {
    "Provider": 0,                   // 缓存提供器
    "Redis": {
      "ConnectionString": "127.0.0.1:6379",
      "DefaultDb": 0,
      "Prefix": "DM"
    }
  }
}
1
2
3
4
5
6
7
8
9
10

# Provider 枚举值

提供器 说明
0 MemoryCache 内存缓存(默认)
1 Redis Redis 分布式缓存
2 Memcached Memcached 分布式缓存

# 4. 日志配置 (Serilog)

{
  "Serilog": {
    "MinimumLevel": {
      "Default": "Information",
      "Override": {
        "Microsoft": "Warning",
        "System": "Warning"
      }
    },
    "WriteTo": [
      {
        "Name": "File",
        "Args": {
          "path": "logs/log-.log",
          "rollingInterval": "Day",
          "retainedFileCountLimit": 30
        }
      }
    ]
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# MinimumLevel 枚举值

级别 说明
Verbose 最详细日志
Debug 调试信息
Information 一般信息(推荐)
Warning 警告信息
Error 错误信息
Fatal 致命错误

# 5. Admin 模块配置

{
  "Admin": {
    "Auditing": true,              // 是否开启审计日志
    "PermissionValidate": true     // 是否开启权限验证
  }
}
1
2
3
4
5
6
配置项 说明 默认值
Auditing 审计日志 true
PermissionValidate 权限验证 true

# 6. 上传配置 (Upload)

{
  "Upload": {
    "UploadPath": "/upload",       // 文件上传路径
    "TempPath": "/temp",           // 临时文件路径
    "MaxSize": 104857600           // 最大文件大小(字节)
  }
}
1
2
3
4
5
6
7

# 📖 读取配置

# 方式一:IOptions 模式(推荐)

// 1. 定义配置类
public class CacheOptions
{
    public int Provider { get; set; }
    public RedisOptions Redis { get; set; }
}

public class RedisOptions
{
    public string ConnectionString { get; set; }
    public int DefaultDb { get; set; }
    public string Prefix { get; set; }
}

// 2. 注册配置
builder.Services.Configure<CacheOptions>(
    builder.Configuration.GetSection("Cache"));

// 3. 注入使用
public class CacheService
{
    private readonly CacheOptions _options;
    
    public CacheService(IOptions<CacheOptions> options)
    {
        _options = options.Value;
    }
    
    public void Connect()
    {
        var connStr = _options.Redis.ConnectionString;
        // 使用配置
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

# 方式二:IOptionsSnapshot 模式(支持热更新)

public class ConfigService
{
    private readonly IOptionsSnapshot<CacheOptions> _options;
    
    public ConfigService(IOptionsSnapshot<CacheOptions> options)
    {
        _options = options;
    }
    
    public void UseConfig()
    {
        // 每次访问都会读取最新配置
        var connStr = _options.Value.Redis.ConnectionString;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 方式三:IOptionsMonitor 模式(监听变化)

public class MonitoringService
{
    private readonly IOptionsMonitor<CacheOptions> _options;
    
    public MonitoringService(IOptionsMonitor<CacheOptions> options)
    {
        _options = options;
        
        // 监听配置变化
        _options.OnChange(newOptions =>
        {
            Console.WriteLine($"配置已更新:{newOptions.Redis.ConnectionString}");
        });
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 方式四:直接读取 IConfiguration

public class LegacyService
{
    private readonly IConfiguration _config;
    
    public LegacyService(IConfiguration config)
    {
        _config = config;
    }
    
    public void UseConfig()
    {
        var connStr = _config["Cache:Redis:ConnectionString"];
        var provider = _config.GetValue<int>("Cache:Provider");
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 🏗️ DarkM 框架的配置扩展

# 配置验证

// Startup.cs 或 Program.cs
builder.Services.AddOptions<CacheOptions>()
    .Bind(builder.Configuration.GetSection("Cache"))
    .Validate(options =>
    {
        if (options.Provider == 1 && string.IsNullOrEmpty(options.Redis.ConnectionString))
        {
            return false; // Redis 模式必须配置连接字符串
        }
        return true;
    }, "Redis 连接字符串不能为空");
1
2
3
4
5
6
7
8
9
10
11

# 模块配置

每个 DarkM 模块可以有自己的配置节:

// AdminModule.cs
public class AdminModule : IModule
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.Configure<AdminOptions>(
            builder.Configuration.GetSection("Admin"));
        
        services.AddScoped<IAccountService, AccountService>();
    }
}

// AdminOptions.cs
public class AdminOptions
{
    public bool Auditing { get; set; } = true;
    public bool PermissionValidate { get; set; } = true;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 💡 最佳实践

# 1. 使用强类型配置

// ✅ 推荐:强类型
public class CacheService
{
    private readonly CacheOptions _options;
    
    public CacheService(IOptions<CacheOptions> options)
    {
        _options = options.Value;
    }
}

// ❌ 避免:字符串读取
public class CacheService
{
    private readonly string _connStr;
    
    public CacheService(IConfiguration config)
    {
        _connStr = config["Cache:Redis:ConnectionString"];
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# 2. 配置类命名规范

// ✅ 推荐:*Options 后缀
public class CacheOptions { }
public class DatabaseOptions { }
public class AdminOptions { }

// ❌ 避免:其他命名
public class CacheConfig { }
public class DatabaseSettings { }
1
2
3
4
5
6
7
8

# 3. 配置验证

// ✅ 推荐:启动时验证
services.AddOptions<DatabaseOptions>()
    .Bind(Configuration.GetSection("Db"))
    .ValidateDataAnnotations()  // 数据注解验证
    .ValidateOnStart();         // 启动时验证

// 配置类使用注解
public class DatabaseOptions
{
    [Required]
    public string ConnectionString { get; set; }
    
    [Range(0, 3)]
    public int Dialect { get; set; }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 4. 环境隔离

# 开发环境
export ASPNETCORE_ENVIRONMENT=Development
dotnet run

# 生产环境
export ASPNETCORE_ENVIRONMENT=Production
dotnet run
1
2
3
4
5
6
7
// appsettings.Development.json
{
  "Db": {
    "Logging": true,  // 开发环境开启 SQL 日志
    "Server": "../../data/SQLite"
  }
}

// appsettings.Production.json
{
  "Db": {
    "Logging": false,  // 生产环境关闭 SQL 日志
    "Server": "prod-db-server"
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 5. 敏感信息保护

# ❌ 避免:明文存储在 appsettings.json
{
  "Db": {
    "UserId": "sa",
    "Password": "MySecretPassword123"
  }
}

# ✅ 推荐:使用用户机密(开发环境)
dotnet user-secrets set "Db:UserId" "sa"
dotnet user-secrets set "Db:Password" "MySecretPassword123"

# ✅ 推荐:使用环境变量(生产环境)
export Db__UserId=sa
export Db__Password=MySecretPassword123

# ✅ 推荐:使用 Azure Key Vault / AWS Secrets Manager
builder.Configuration.AddAzureKeyVault(...);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 🔍 常见问题

# Q1: 配置不生效?

检查清单:

  1. ✅ 配置文件是否已复制到输出目录?
  2. ✅ 配置节名称是否匹配?
  3. ✅ 配置类属性名是否与 JSON 一致(大小写敏感)?
  4. ✅ 是否在 ConfigureServices 中注册了配置?

# Q2: 如何读取数组配置?

{
  "Db": {
    "Modules": [
      { "Name": "Admin", "Database": "Nm_Admin" },
      { "Name": "Common", "Database": "Nm_Common" }
    ]
  }
}
1
2
3
4
5
6
7
8
public class DatabaseOptions
{
    public List<ModuleOptions> Modules { get; set; }
}

public class ModuleOptions
{
    public string Name { get; set; }
    public string Database { get; set; }
}

// 使用
var dbOptions = _options.Value;
foreach (var module in dbOptions.Modules)
{
    Console.WriteLine($"{module.Name}: {module.Database}");
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# Q3: 如何动态更新配置?

// 使用 IOptionsSnapshot 或 IOptionsMonitor
public class DynamicConfigService
{
    private readonly IOptionsMonitor<CacheOptions> _options;
    
    public DynamicConfigService(IOptionsMonitor<CacheOptions> options)
    {
        _options = options;
        
        // 监听变化
        _options.OnChange(newOptions =>
        {
            // 重新初始化缓存连接
            Reconnect(newOptions);
        });
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 📚 相关文档


# 🔗 参考链接


最后更新: 2024-09-20