Як сконфігурувати сервіс за допомогою конфігуратора

Дата оновлення перекладу 2022-11-25

Як сконфігурувати сервіс за допомогою конфігуратора

Конфигуратор сервісу - це функція сервіс-контейнера, яка дозволяє вам використовувати викличне, щоб сконфігурувати сервіс після його інстанціювання.

Конфігуратор сервісу може бути використаний, наприклад, коли у вас є сервіс, який вимагає складної установки, заснованої на налаштуваннях конфігурації, що походять з різних джерел або сервісів. Використовуючи зовнішній конфігуратор, ви можете підтримувати реалізацію сервісу у чистоті та тримати її окремо від інших обʼєктів, які надають необхідну конфігурацію..

Ще один приклад використання - коли у вас є багато обʼєктів, які сумісно використовують спільну конфігурацію, або які повинні бути сконфігуровані під час рантайму схожим чином.

Наприклад, уявіть, що у вас є додаток, де ви надсилаєте різні види електронних листів користувача. Листи пропускаються через різноманітні програми форматування, які можуть бути включені або ні, в залежності від деяких динамічних налаштувань додатку. Ви починаєте визначати клас NewsletterManager таким чином:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// src/Mail/NewsletterManager.php
namespace App\Mail;

class NewsletterManager implements EmailFormatterAwareInterface
{
    private $enabledFormatters;

    public function setEnabledFormatters(array $enabledFormatters): void
    {
        $this->enabledFormatters = $enabledFormatters;
    }

    // ...
}

а також клас GreetingCardManager:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// src/Mail/GreetingCardManager.php
namespace App\Mail;

class GreetingCardManager implements EmailFormatterAwareInterface
{
    private $enabledFormatters;

    public function setEnabledFormatters(array $enabledFormatters): void
    {
        $this->enabledFormatters = $enabledFormatters;
    }

    // ...
}

Як згадувалось раніше, ціллю є встановити програми формтування під час рантайму, в залежності від налаштувань додатку. Щоб зробити це, у вас також є клас EmailFormatterManager, який відповідає за завантаження та валідацію програм форматування, включених у додатку:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// src/Mail/EmailFormatterManager.php
namespace App\Mail;

class EmailFormatterManager
{
    // ...

    public function getEnabledFormatters(): array
    {
        // код для конфігурації того, які програми форматування використовувати
        $enabledFormatters = [...];

        // ...

        return $enabledFormatters;
    }
}

Якщо вашою ціллю є уникнути обʼєднання NewsletterManager та GreetingCardManager з EmailFormatterManager, то ви можете захотіти створити клас конфігуратора для конфігурування цих екземплярів:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// src/Mail/EmailConfigurator.php
namespace App\Mail;

class EmailConfigurator
{
    private $formatterManager;

    public function __construct(EmailFormatterManager $formatterManager)
    {
        $this->formatterManager = $formatterManager;
    }

    public function configure(EmailFormatterAwareInterface $emailManager): void
    {
        $emailManager->setEnabledFormatters(
            $this->formatterManager->getEnabledFormatters()
        );
    }

    // ...
}

Робота EmailConfigurator - впроваджувати включені програми форматування у NewsletterManager та GreetingCardManager, тому що вони не знають, звідки зʼявилися включені програми форматування. З іншої сторони, EmailFormatterManager містить дані про включені програми форматування та про те, як їх завантажувати, підтримуючи єдиний принцип відповідальності.

Tip

В той час як цей приклад використовує метод PHP-класу, конфігуратори можуть бути будь-яким PHP-викличним, включно з функціями, статичними методами та методами сервісів.

Використання конфігуратора

Ви можете сконфігурувати конфігуратор сервісу, використовуючи опцію configurator. Якщо ви використовуєте конфігурацію services.yml за замовчуванням , то всі класи вже завантажені як сервіси. Все, що вам потрібно зробити - це чітко визначити configurator:

  • YAML
  • XML
  • PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# app/config/services.yml
services:
    # ...

    # Реєструє всі 4 класи як сервіси, включно з AppBundle\Mail\EmailConfigurator
    App\:
        resource: '../src/*'
        # ...

    # перевизначити сервіси, щоб встановити конфігуратор
    App\Mail\NewsletterManager:
        configurator: ['@App\Mail\EmailConfigurator', 'configure']

    App\Mail\GreetingCardManager:
        configurator: ['@App\Mail\EmailConfigurator', 'configure']

Сервіси можуть бути сконфігуровані через викличні конфігуратори (заміняючи метод configure() на __invoke()), шляхом пропуску імені методу:

  • YAML
  • XML
  • PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# config/services.yaml
services:
    # ...

    # реєструє всі класи як сервіси, включно з App\Mail\EmailConfigurator
    App\:
        resource: '../src/*'
        # ...

    # перевизначити сервіси, щоб встановити конфігуратор
    App\Mail\NewsletterManager:
        configurator: '@App\Mail\EmailConfigurator'

    App\Mail\GreetingCardManager:
        configurator: '@App\Mail\EmailConfigurator'

Ось і все! При запиті сервісу AppBundle\Mail\NewsletterManager або AppBundle\Mail\GreetingCardManager, створений екземпляр спочатку буде переданий у метод EmailConfigurator::configure().