Использование фабрики для создания сервисов в сервис-контейнер Symfony.

Сервис-контейнер Symfony предоставляет множество функций для управления созданием объектов, позволяя вам указывать аргументы, передаваемые конструктору, а также вызывать методы и задавать параметры.

Однако иногда вам необходимо применить шаблон проектирования Фабрика, чтобы делегировать создание объекта какому-то специальному объекту, называемому «фабрика». В этих случаях сервисный контейнер может вызвать метод вашей фабрики, чтобы создать объект, а не напрямую создавать экземпляр класса.

Статическая фабрика.

Предположим, у вас есть фабрика, которая настраивает и возвращает новый объект NewsletterManager, вызывая статический метод createNewsletterManager():

class NewsletterManagerStaticFactory
{
    public static function createNewsletterManager()
    {
        $newsletterManager = new NewsletterManager();

        // ...

        return $newsletterManager;
    }
}

Чтобы сделать объект NewsletterManager доступным в качестве сервиса, используйте параметр фабрики, чтобы определить, какой метод какого класса должен быть вызван для создания его объекта:

# config/services.yaml
services:
    # ...

    App\Email\NewsletterManager:
        # the first argument is the class and the second argument is the static method
        factory: ['App\Email\NewsletterManagerStaticFactory', 'createNewsletterManager']

При использовании фабрики для создания сервисов значение, выбранное для класса, не влияет на результирующий сервис. Фактическое имя класса зависит только от объекта, возвращаемого фабрикой. Однако сконфигурированное имя класса может использоваться проходами компилятора и поэтому должно быть установлено в разумное значение.

Фабрика нестатическая.

Если ваша фабрика использует обычный метод вместо статического для настройки и создания сервиса, то создайте экземпляр самой фабрики как сервис. Конфигурация сервисного контейнера выглядит следующим образом:

# config/services.yaml
services:
    # ...

    # first, create a service for the factory
    App\Email\NewsletterManagerFactory: ~

    # second, use the factory service as the first argument of the 'factory'
    # option and the factory method as the second argument
    App\Email\NewsletterManager:
        factory: ['@App\Email\NewsletterManagerFactory', 'createNewsletterManager']

Invokable Factories.

Предположим, что теперь вы изменили свой фабричный метод на __invoke(), чтобы ваш фабричный сервис можно было использовать в качестве обратного вызова:

class InvokableNewsletterManagerFactory
{
    public function __invoke()
    {
        $newsletterManager = new NewsletterManager();

        // ...

        return $newsletterManager;
    }
}

Сервисы можно создавать и настраивать с помощью таких вызываемых фабрик, опуская имя магического метода __invoke().

# config/services.yaml
services:
    # ...

    App\Email\NewsletterManager:
        class:   App\Email\NewsletterManager
        factory: '@App\Email\NewsletterManagerFactory'

Передача аргументов в фабричный метод.

Аргументы вашего фабричного метода автоматически подключаются, если он включен для вашего сервиса

Если вам нужно передать аргументы фабричному методу, вы можете использовать опцию arguments. Например, предположим, что метод createNewsletterManager() в предыдущих примерах принимает сервис шаблонов в качестве аргумента:

# config/services.yaml
services:
    # ...

    App\Email\NewsletterManager:
        factory:   ['@App\Email\NewsletterManagerFactory', createNewsletterManager]
        arguments: ['@templating']

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *