# INI 配置提供程序

Source: https://docs.sisk-framework.org/zh-cn/docs/extensions/ini-configuration.html

Sisk 提供了一种获取除 JSON 之外的启动配置的方法。实际上，任何实现了 [IConfigurationReader](https://docs.sisk-framework.org/api/Sisk.Core.Http.Hosting.IConfigurationReader.md) 的管道都可以与 [PortableConfigurationBuilder.WithConfigurationPipeline](https://docs.sisk-framework.org/api/Sisk.Core.Http.Hosting.PortableConfigurationBuilder.md) 一起使用，从任意文件类型读取服务器配置。

[Sisk.IniConfiguration](https://www.nuget.org/packages/Sisk.IniConfiguration/) 包提供了基于流的 INI 文件读取器，能够对常见语法错误不抛出异常，并且拥有简洁的配置语法。该包可在 Sisk 框架之外使用，为需要高效 INI 文档读取器的项目提供灵活性。

## 安装

要安装该包，可以使用以下命令：

```bash
$ dotnet add package Sisk.IniConfiguration
```

你也可以安装核心包，该包不包含 INI [IConfigurationReader](https://docs.sisk-framework.org/api/Sisk.Core.Http.Hosting.IConfigurationReader)，也不依赖 Sisk，仅提供 INI 序列化器：

```bash
$ dotnet add package Sisk.IniConfiguration.Core
```

使用主包时，你可以在代码中按下面示例使用：

```cs
class Program
{
    static HttpServerHostContext Host = null!;

    static void Main(string[] args)
    {
        Host = HttpServer.CreateBuilder()
            .UsePortableConfiguration(config =>
            {
                config.WithConfigFile("app.ini", createIfDontExists: true);
                
                // 使用 IniConfigurationReader 配置读取器
                config.WithConfigurationPipeline<IniConfigurationReader>();
            })
            .UseRouter(r =>
            {
                r.MapGet("/", SayHello);
            })
            .Build();
        
        Host.Start();
    }

    static HttpResponse SayHello(HttpRequest request)
    {
        string? name = Host.Parameters["name"] ?? "world";
        return new HttpResponse($"Hello, {name}!");
    }
}
```

上述代码会在进程的当前目录（CurrentDirectory）查找 app.ini 文件。INI 文件示例如下：

```ini
[Server]
# 支持多个监听地址
Listen = http://localhost:5552/
Listen = http://localhost:5553/
ThrowExceptions = false
AccessLogsStream = console

[Cors]
AllowMethods = GET, POST
AllowHeaders = Content-Type, Authorization
AllowOrigin = *

[Parameters]
Name = "Kanye West"
```

## INI 风格与语法

当前实现的风格：

- 属性和节名称 **不区分大小写**。
- 属性名和属性值会 **去除首尾空白**，除非值被引号包裹。
- 值可以使用单引号或双引号括起来。引号内部可以包含换行。
- 支持使用 `#` 和 `;` 进行注释。同时，**允许行尾注释**。
- 属性可以拥有多个值。

详细说明 Sisk 使用的 INI 解析器 “风格” 文档请参见[此文档](https://github.com/sisk-http/archive/blob/master/ext/ini-reader-syntax.md)。

以下 ini 代码示例：

```ini
One = 1
Value = this is an value
Another value = "this value
    has an line break on it"

; 以下代码包含一些颜色
[some section]
Color = Red
Color = Blue
Color = Yellow ; 不要使用黄色
```

使用以下方式解析：

```csharp
// 从字符串解析 ini 文本
IniDocument doc = IniDocument.FromString(iniText);

// 获取单个值
string? one = doc.Global.GetOne("one");
string? anotherValue = doc.Global.GetOne("another value");

// 获取多个值
string[]? colors = doc.GetSection("some section")?.GetMany("color");
```

## 配置参数

| 节和名称 | 是否允许多个值 | 描述 |
| ---------------- | --------------------- | ----------- |
| `Server.Listen` | Yes | 服务器监听地址/端口。 |
| `Server.Encoding` | No | 服务器默认编码。 |
| `Server.MaximumContentLength` | No | 服务器最大 content-length 大小（字节）。如果省略，则保持服务器默认值（自 Sisk 1.7 起为 100 MB）。使用 `0` 表示无限制。 |
| `Server.IncludeRequestIdHeader` | No | 指定 HTTP 服务器是否应发送 X-Request-Id 头。 |
| `Server.ThrowExceptions` | No | 指定是否应抛出未处理的异常。 |
| `Server.AccessLogsStream` | No | 指定访问日志输出流。 |
| `Server.ErrorsLogsStream` | No | 指定错误日志输出流。 |
| `Cors.AllowMethods` | No | 指定 CORS Allow-Methods 头的值。 |
| `Cors.AllowHeaders` | No | 指定 CORS Allow-Headers 头的值。 |
| `Cors.AllowOrigins` | No | 指定多个 Allow-Origin 头，使用逗号分隔。更多信息请参见 [AllowOrigins](https://docs.sisk-framework.org/api/Sisk.Core.Entity.CrossOriginResourceSharingHeaders.AllowOrigins.md)。 |
| `Cors.AllowOrigin` | No | 指定单个 Allow-Origin 头。 |
| `Cors.ExposeHeaders` | No | 指定 CORS Expose-Headers 头的值。 |
| `Cors.AllowCredentials` | No | 指定 CORS Allow-Credentials 头的值。 |
| `Cors.MaxAge` | No | 指定 CORS Max-Age 头的值。 |
