> For the complete documentation index, see [llms.txt](https://monksoul.gitbook.io/hoa/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://monksoul.gitbook.io/hoa/peizhiguanli.md).

# 十五、配置管理

## 什么是配置

简单来说，配置就是将系统应用可动态调配的选项放在统一地方管理。

## 如何配置

在 asp.net core 应用程序中，通常配置都是存放在 `.json` 文件中，在Hoa Framework 中，建议存放在 `Hoa.Web.Host.appsetting.json` 中，当然也是 asp.net core 建议方式。

在 `.json` 文件配置中的所有 `键` 必须采用双引号包裹。如：

```javascript
{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  }
}
```

## 读取配置的方式

* 直接通过 `IConfiguration` 读取
* 通过[选项方式](https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/configuration/options?view=aspnetcore-3.1)载入配置文件，实现热更&#x65B0;**（推荐）**
* 框架内置快捷读取

### 直接读取

直接读取 `appsetting.json` 配置信息主要是通过 `IConfiguration` 实例对象来读取，可通过构造函数注入：

假设 `appsetting.json` 中有一个 `Person` 配置节点：

```javascript
{
  "Person": {
    "Name": "MonkSoul",
    "Age": 27,
    "Gender": "男"
  }
}
```

```csharp
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Extensions.Configuration;

namespace Hoa.Application.Test
{
    [HoaServiceController]
    public class TestAppService : ITestAppService, IAppServiceDependency
    {
        private readonly IConfiguration _configuration;
        public TestAppService(IConfiguration configuration)
        {
             _configuration = configuration;
        }
        
        public void ConsolePerson()
        {
            var name = _configuration["Person:Name"];
            var age = _configuration["Age"];
            var gender = _configuration["Person:Gender"];
        }
    }
}

```

读取具体的键值只需要通过 `:` 语法即可，如：`{键名称}:{下一级键名称}:{下下一级键名称}...`

更多直接读取配置信息方式[可查看官方文档](https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/configuration/?view=aspnetcore-3.1)。

### 选项模式

选项模式是 asp.net core 推荐的动态读取配置的方式，这种方式将配置文件数据用一个强类型来托管，能够实现默认值设置，动态热加载等等功能。

针对上述的 `Person` 配置，我们需要创建一个一一对应的强类型 `PersonOptions` ：

```csharp
public class PersonOptions
{
    public string Name { get; set;}
    public int Age { get; set;}
    public string Gender { get; set;}
}
```

接下来，我们只需要 `Hoa.Web.Core.ServiceExtensions.HoaConfigurationInitiateExtension.cs`配置即可，如：

```csharp
var personOptions = Configuration.GetSection(nameof(Person));
services.Configure<PersonOptions>(personOptions, options => { });
```

这样我们便可以在构造函数中注入使用了

```csharp
using Hoa.AppConfigure;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;

namespace Hoa.Web.Host.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class HoaController : ControllerBase
    {
        private readonly PersonOptions personOptions;
        public HoaController(IOptionsMonitor<PersonOptions> optionsMonitor)
        {
            personOptions = optionsMonitor.CurrentValue;
            
            // personOptions.Name
            // personOptions.Age
        }
    }
}
```

关于选项模式[可查看官方文档](https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/configuration/options?view=aspnetcore-3.1)。

### 内置便捷选项读取

为了快速开发，Hoa Framework 内置了一些预设的选项读取属性，如：

* `AppGlobal.AppConfigOptions` ：获取全局配置信息，对应 `appsetting.json` 中的 `AppConfingOptions` 节点。
* `AppGlobal.CorsConfigOptions` ：获取跨域配置信息，对应 `appsetting.json` 中的 `CorsConfigOptions` 节点。
* `AppGlobal.SwaggerOptions` ：获取Swagger配置信息，对应 `appsetting.json` 中的 `HoaSwaggerOptions` 节点。
* `AppGlobal.JwtOptions` ：获取JWT配置信息，对应 `appsetting.json` 中的 `HoaJwtOptions` 节点。

除此之外，框架还提供了 `AppGlobal.Configuration` 属性，可以免构造函数注入方式获取配置信息，如：

```csharp
AppGlobal.Configuration["Person:Name"]
```

## 内置配置说明

Hoa Framework 框架默认提供一些应用配置需求，相关配置在 `Hoa.Web.Host` 项目下的 `appsetting.json` 中：

```javascript
{
  "ConnectionStrings": {
    "HoaDatabase": "Server=localhost;Database=Hoa;User=sa;Password=******;"
  },
  "AppConfigOptions": {
    "EnableGlobalAuthorizationFilter": false,
    "EnableGlobalUnifiedResultFilter": true,
    "EnableCorsSupport": false,
    "EnableGlobalPerformanceAnalysis": true,
    "EnableTenantMode": false
  },
  "CorsConfigOptions": {
    "PolicyName": "HoaAllowSpecificOrigins",
    "Origins": [
      "http://example.com",
      "http://www.contoso.com"
    ]
  },
  "HoaJwtOptions": {
    "HeaderKey": "Authorization",
    "SecurityKey": "wBPSILd@bHMxV1H!Pvc9eYMYdsyttpGl",
    "Audience": "Hoa.Client",
    "Issuer": "Hoa.Server",
    "AuthorizationClassify": "classify",
    "ClockSkewSeconds": 30,
    "ExpiredTime": 20
  },
  "HoaSwaggerOptions": {
    "DocumentTitle": "Hoa RESTFul API",
    "SecurityDefinitionName": "Bearer",
    "UnClassifiedName": "Default",
    "IsShowMSTestSummary": true,
    "Groups": {
      "Default": {
        "Title": "Default RESTFul API",
        "Description": "This is default restful api description.",
        "TermsOfService": "",
        "Contact": {
          "Name": "Monk",
          "Email": "monksoul@outlook.com",
          "Url": ""
        },
        "License": {
          "Name": "",
          "Url": ""
        }
      }
    }
  }
}
```

### 节点配置说明

* `ConnectionStrings`：数据库连接字符串配置选项，支持多个连接字符串配置
  * `HoaDatabase`：框架默认数据库连接字符串名称
* `AppConfigOptions`：应用全局配置选项
  * `EnableGlobalAuthorizationFilter`：是否启用全局授权过滤器，默认 `false`，设置为 `true` 后，所有的WebApi都需授权才能访问
  * `EnableGlobalUnifiedResultFilter`：是否启用全局规范化返回接口，默认 `true`，设置为 `false` 后，直接返回不统一的结果，**建议设置为 `true`**
  * `EnableCorsSupport`：是否启用跨域支持，默认 `false`，设置为 `true` 后，**需配置 `CorsConfigOptions` 选项**
  * `EnableGlobalPerformanceAnalysis`：是否启用全局性能分析器，默认 `true`，设置为 `false` 后，不再显示详细的性能分析，**建议部署上线后设置为 `false`**
  * `EnableTenantMode`：是否启用Saas多租户模式，默认为false
* `CorsConfigOptions`：跨域配置选项
  * `PolicyName`：策略名称
  * `Origins`：允许来源配置，`string[]类型`
* `HoaJwtOptions`：Jwt授权配置选项
  * `HeaderKey`：授权检查请求报文头 Headers 名称，默认为 `Authorization`
  * `SecurityKey`：Jwt Token 校验所需密钥，建议长度在 **16** 位以上
  * `Audience`：Jwt 接受授权的一方，通常为客户端信息
  * `Issuer`：Jwt 签发方
  * `AuthorizationClassify`：实现多系统权限控制 Jwt Claim 标识
  * `ClockSkewSeconds`：Jwt 有效生命周期的容错值，单位为秒，默认30s
  * `ExpiredTime`：Jwt Token过期时间，单位分钟，默认20分钟
* `HoaSwaggerOptions`：Swagger 文档配置选项
  * `DocumentTitle`：文档标题
  * `SecurityDefinitionName`：授权 `Schema`，系统基于Jwt授权，所以是 `Bearer`
  * `UnclassifiedName`：默认文档名称
  * `IsShowMSTestSummary`：是否启用汇总单元测试类
  * `Groups`：多个版本API配置信息，支持多个动态配置，Key 为版本名称
    * `Default`：版本名称
      * `Title`：API标题
      * `Description`：描述
      * `TermsOfService`合约地址
      * `Contact`：联系信息
        * `Name`：联系人名称
        * `Email`：联系人邮箱
        * `Url`：联系人主页
      * `License`：协议
        * `Name`：协议名称
        * `Url`：协议地址
