Как внедрять значения, основанные на сложных выражениях

Как внедрять значения, основанные на сложных выражениях

Сервис-контейнер также поддерживает "выражение", которое позволяет вам внедрять очень особенные значения в сервис.

Например, представьте, что у вас есть сервис (здесь не показан), под названием AppBundle\Mail\MailerConfiguration, который в себе имеет метод getMailerMethod(). Он возвращает строку вроде sendmail, основываясь на какой-то конфигурации.

Представьте, что вы хотите передать результат этого метода в качестве аргумента конструктора другому сервису: AppBundle\Mailer. Одним из способов сделать это - с помощью выражения:

  • YAML
    1
    2
    3
    4
    5
    6
    7
    8
    # app/config/config.yml
    services:
        # ...
    
        AppBundle\Mail\MailerConfiguration: ~
    
        AppBundle\Mailer:
            arguments: ["@=service('AppBundle\Mail\MailerConfiguration').getMailerMethod()"]
    
  • XML
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    <!-- app/config/config.xml -->
    <?xml version="1.0" encoding="UTF-8" ?>
    <container xmlns="http://symfony.com/schema/dic/services"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://symfony.com/schema/dic/services
            http://symfony.com/schema/dic/services/services-1.0.xsd">
    
        <services>
            <!-- ... -->
    
            <service id="AppBundle\Mail\MailerConfiguration"></service>
    
            <service id="AppBundle\Mailer">
                <argument type="expression">service('AppBundle\Mail\MailerConfiguration').getMailerMethod()</argument>
            </service>
        </services>
    </container>
    
  • PHP
    1
    2
    3
    4
    5
    6
    7
    8
    9
    // app/config/config.php
    use AppBundle\Mail\MailerConfiguration;
    use AppBundle\Mailer;
    use Symfony\Component\ExpressionLanguage\Expression;
    
    $container->autowire(AppBundle\Mail\MailerConfiguration::class);
    
    $container->autowire(Mailer::class)
        ->addArgument(new Expression('service("AppBundle\Mail\MailerConfiguration").getMailerMethod()'));
    

Чтобы узнать больше о синтаксисе языка выражений, см. The Expression Syntax.

В этом контексте, у вас есть доступ к 2 функциям:

service
Возвращает данный сервис (смотрите пример выше).
parameter
Возвращает конкретное значение параметра (синтаксис такой же, как в service).

Вы также имеете доступ к ContainerBuilder через переменную container. Вот ещё один пример:

  • YAML
    1
    2
    3
    services:
        AppBundle\Mailer:
            arguments: ["@=container.hasParameter('some_param') ? parameter('some_param') : 'default_value'"]
    
  • XML
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    <?xml version="1.0" encoding="UTF-8" ?>
    <container xmlns="http://symfony.com/schema/dic/services"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://symfony.com/schema/dic/services
            http://symfony.com/schema/dic/services/services-1.0.xsd">
    
        <services>
            <service id="AppBundle\Mailer">
                <argument type="expression">container.hasParameter('some_param') ? parameter('some_param') : 'default_value'</argument>
            </service>
        </services>
    </container>
    
  • PHP
    1
    2
    3
    4
    5
    6
    7
    use AppBundle\Mailer;
    use Symfony\Component\ExpressionLanguage\Expression;
    
    $container->autowire(Mailer::class)
        ->addArgument(new Expression(
            "container.hasParameter('some_param') ? parameter('some_param') : 'default_value'"
        ));
    

Выражения могут быть использованы в arguments, properties, в качестве аргументов с configurator и аргументов к calls (вызовы метода).

Эта документация является переводом официальной документации Symfony и предоставляется по свободной лицензии CC BY-SA 3.0.