# Поставщики сервисов

Source: https://docs.sisk-framework.org/ru/docs/extensions/service-providers.html

Поставщики сервисов — это способ перенести ваше приложение Sisk в разные среды с помощью переносимого файла конфигурации. Эта возможность позволяет изменять порт сервера, параметры и другие опции, не меняя код приложения для каждой среды. Этот модуль зависит от синтаксиса построения Sisk и может быть настроен через метод UsePortableConfiguration.

Поставщик конфигурации реализуется с помощью IConfigurationProvider, который предоставляет считыватель конфигурации и может принимать любую реализацию. По умолчанию Sisk предоставляет JSON‑считыватель конфигурации, но также существует пакет для INI‑файлов. Вы также можете создать собственный поставщик конфигурации и зарегистрировать его с помощью:

```csharp
using var app = HttpServer.CreateBuilder()
    .UsePortableConfiguration(config =>
    {
        config.WithConfigReader<MyConfigurationReader>();
    })
    .Build();
```

Как упоминалось ранее, провайдер по умолчанию — это JSON‑файл. По умолчанию ищется файл с именем service-config.json, и поиск производится в текущем каталоге работающего процесса, а не в каталоге исполняемого файла.

Вы можете изменить имя файла, а также указать, где Sisk должен искать файл конфигурации, с помощью:

```csharp
using Sisk.Core.Http;
using Sisk.Core.Http.Hosting;

using var app = HttpServer.CreateBuilder()
    .UsePortableConfiguration(config =>
    {
        config.WithConfigFile("config.toml",
            createIfDontExists: true,
            lookupDirectories:
                ConfigurationFileLookupDirectory.CurrentDirectory |
                ConfigurationFileLookupDirectory.AppDirectory);
    })
    .Build();
```

Приведённый выше код будет искать файл config.toml в текущем каталоге работающего процесса. Если файл не найден, будет выполнен поиск в каталоге, где находится исполняемый файл. Если файл не существует, параметр createIfDontExists будет учтён: файл будет создан без содержимого в последнем проверенном пути (в зависимости от lookupDirectories), и в консоли будет выведена ошибка, препятствующая инициализации приложения.

> [!TIP]
> 
> Вы можете посмотреть исходный код INI‑считывателя конфигурации и JSON‑считывателя конфигурации, чтобы понять, как реализован IConfigurationProvider.

## Чтение конфигураций из JSON‑файла

По умолчанию Sisk предоставляет поставщик конфигурации, который читает настройки из JSON‑файла. Этот файл имеет фиксированную структуру и состоит из следующих параметров:

```json
{
    "Server": {
        "DefaultEncoding": "UTF-8",
        "ThrowExceptions": true,
        "IncludeRequestIdHeader": true
    },
    "ListeningHost": {
        "Label": "My sisk application",
        "Ports": [
            "http://localhost:80/",
            "https://localhost:443/",  // Файлы конфигурации также поддерживают комментарии
        ],
        "CrossOriginResourceSharingPolicy": {
            "AllowOrigin": "*",
            "AllowOrigins": [ "*" ],   // новое в версии 0.14
            "AllowMethods": [ "*" ],
            "AllowHeaders": [ "*" ],
            "MaxAge": 3600
        },
        "Parameters": {
            "MySqlConnection": "server=localhost;user=root;"
        }
    }
}
```

Параметры, созданные из файла конфигурации, можно получить в конструкторе сервера:

```csharp
using var app = HttpServer.CreateBuilder()
    .UsePortableConfiguration(config =>
    {
        config.WithParameters(paramCollection =>
        {
            string databaseConnection = paramCollection.GetValueOrThrow("MySqlConnection");
        });
    })
    .Build();
```

Каждый считыватель конфигурации предоставляет способ чтения параметров инициализации сервера. Некоторые свойства указываются в окружении процесса, а не в файле конфигурации, например чувствительные данные API, ключи API и т.д.

## Структура файла конфигурации

<table>
    <thead>
        <tr>
            <th>Свойство</th>
            <th>Обязательно</th>
            <th>Описание</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>Server</td>
            <td>Required</td>
            <td>Представляет сам сервер с его настройками.</td>
        </tr>
        <tr>
            <td>Server.AccessLogsStream</td>
            <td>Optional</td>
            <td>По умолчанию <code>console</code>. Указывает поток вывода журнала доступа. Может быть именем файла, <code>null</code> или <code>console</code>.</td>
        </tr>
        <tr>
            <td>Server.ErrorsLogsStream</td>
            <td>Optional</td>
            <td>По умолчанию <code>null</code>. Указывает поток вывода журнала ошибок. Может быть именем файла, <code>null</code> или <code>console</code>.</td>
        </tr>
        <tr>
            <td>Server.MaximumContentLength</td>
            <td>Optional</td>
            <tr>
            <td>Server.MaximumContentLength</td>
            <td>Optional</td>
            <td>Указывает максимальную длину содержимого в байтах. Ноль означает бесконечность. Когда объект <code>Server</code> присутствует и это свойство опущено, значение равно <code>0</code> (бесконечно), что переопределяет значение по умолчанию 100 МБ свойства <a href="/api/Sisk.Core.Http.HttpServerConfiguration.MaximumContentLength">HttpServerConfiguration.MaximumContentLength</a>.</td>
        </tr>
        <tr>
            <td>Server.IncludeRequestIdHeader</td>
            <td>Optional</td>
            <td>По умолчанию <code>false</code>. Указывает, должен ли HTTP‑сервер отправлять заголовок <code>X-Request-Id</code>.</td>
        </tr>
        <tr>
            <td>Server.ThrowExceptions</td>
            <td>Optional</td>
            <td>По умолчанию <code>true</code>. Указывает, должны ли выбрасываться необработанные исключения. Установите <code>false</code> в продакшн‑среде и <code>true</code> при отладке.</td>
        </tr>
        <tr>
            <td>ListeningHost</td>
            <td>Required</td>
            <td>Представляет хост, прослушиваемый сервером.</td>
        </tr>
        <tr>
            <td>ListeningHost.Label</td>
            <td>Optional</td>
            <td>Представляет метку приложения.</td>
        </tr>
        <tr>
            <td>ListeningHost.Ports</td>
            <td>Required</td>
            <td>Представляет массив строк, соответствующий синтаксису <a href="/api/Sisk.Core.Http.ListeningPort">ListeningPort</a>.</td>
        </tr>
        <tr>
            <td>ListeningHost.CrossOriginResourceSharingPolicy</td>
            <td>Optional</td>
            <td>Настраивает заголовки CORS для приложения.</td>
        </tr>
        <tr>
            <td>ListeningHost.CrossOriginResourceSharingPolicy.AllowCredentials</td>
            <td>Optional</td>
            <td>По умолчанию <code>false</code>. Указывает заголовок <code>Allow-Credentials</code>.</td>
        </tr>
        <tr>
            <td>ListeningHost.CrossOriginResourceSharingPolicy.ExposeHeaders</td>
            <td>Optional</td>
            <td>По умолчанию <code>null</code>. Ожидает массив строк. Указывает заголовок <code>Expose-Headers</code>.</td>
        </tr>
        <tr>
            <td>ListeningHost.CrossOriginResourceSharingPolicy.AllowOrigin</td>
            <td>Optional</td>
            <td>По умолчанию <code>null</code>. Ожидает строку. Указывает заголовок <code>Allow-Origin</code>.</td>
        </tr>
        <tr>
            <td>ListeningHost.CrossOriginResourceSharingPolicy.AllowOrigins</td>
            <td>Optional</td>
            <td>По умолчанию <code>null</code>. Ожидает массив строк. Указывает несколько заголовков <code>Allow-Origin</code>. См. <a href="/api/Sisk.Core.Entity.CrossOriginResourceSharingHeaders.AllowOrigins">AllowOrigins</a> для получения дополнительной информации.</td>
        </tr>
        <tr>
            <td>ListeningHost.CrossOriginResourceSharingPolicy.AllowMethods</td>
            <td>Optional</td>
            <td>По умолчанию <code>null</code>. Ожидает массив строк. Указывает заголовок <code>Allow-Methods</code>.</td>
        </tr>
        <tr>
            <td>ListeningHost.CrossOriginResourceSharingPolicy.AllowHeaders</td>
            <td>Optional</td>
            <td>По умолчанию <code>null</code>. Ожидает массив строк. Указывает заголовок <code>Allow-Headers</code>.</td>
        </tr>
        <tr>
            <td>ListeningHost.CrossOriginResourceSharingPolicy.MaxAge</td>
            <td>Optional</td>
            <td>По умолчанию <code>null</code>. Ожидает целое число. Указывает заголовок <code>Max-Age</code> в секундах.</td>
        </tr>
        <tr>
            <td>ListeningHost.Parameters</td>
            <td>Optional</td>
            <td>Указывает свойства, передаваемые методу настройки приложения.</td>
        </tr>
    </tbody>
</table>
