diff --git a/book/includes/_service_container_my_mailer.rst.inc b/book/includes/_service_container_my_mailer.rst.inc new file mode 100644 index 00000000000..efc2eaeac26 --- /dev/null +++ b/book/includes/_service_container_my_mailer.rst.inc @@ -0,0 +1,36 @@ +.. configuration-block:: + + .. code-block:: yaml + + # app/config/config.yml + services: + my_mailer: + class: Acme\HelloBundle\Mailer + arguments: [sendmail] + + .. code-block:: xml + + + + + + + + sendmail + + + + + .. code-block:: php + + // app/config/config.php + use Symfony\Component\DependencyInjection\Definition; + + $container->setDefinition('my_mailer', new Definition( + 'Acme\HelloBundle\Mailer', + array('sendmail') + )); \ No newline at end of file diff --git a/book/service_container.rst b/book/service_container.rst index 84ef36c0c01..ff355e44f8a 100644 --- a/book/service_container.rst +++ b/book/service_container.rst @@ -103,40 +103,7 @@ for you. In order for this to work, you must *teach* the container how to create the ``Mailer`` service. This is done via configuration, which can be specified in YAML, XML or PHP: -.. configuration-block:: - - .. code-block:: yaml - - # app/config/config.yml - services: - my_mailer: - class: Acme\HelloBundle\Mailer - arguments: [sendmail] - - .. code-block:: xml - - - - - - - - sendmail - - - - - .. code-block:: php - - // app/config/config.php - use Symfony\Component\DependencyInjection\Definition; - - $container->setDefinition('my_mailer', new Definition( - 'Acme\HelloBundle\Mailer', - array('sendmail') - )); +.. include includes/_service_container_my_mailer.rst.inc .. note:: @@ -660,6 +627,113 @@ service needs the ``my_mailer`` service in order to function. When you define this dependency in the service container, the container takes care of all the work of instantiating the classes. +Using the Expression Language +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. versionadded:: 2.4 + The Expression Language functionality was introduced in Symfony 2.4. + +The service container also supports an "expression" that allows you to inject +very specific values into a service. + +For example, suppose you have a third service (not shown here), called ``mailer_configuration``, +which has a ``getMailerMethod()`` method on it, which will return a string +like ``sendmail`` based on some configuration. Remember that the first argument +to the ``my_mailer`` service is the simple string ``sendmail``: + +.. include includes/_service_container_my_mailer.rst.inc + +But instead of hardcoding this, how could we get this value from the ``getMailerMethod()`` +of the new ``mailer_configuration`` service? One way is to use an expression: + +.. configuration-block:: + + .. code-block:: yaml + + # app/config/config.yml + services: + my_mailer: + class: Acme\HelloBundle\Mailer + arguments: ["@=service('mailer_configuration').getMailerMethod()"] + + .. code-block:: xml + + + + + + + + service('mailer_configuration').getMailerMethod() + + + + + .. code-block:: php + + // app/config/config.php + use Symfony\Component\DependencyInjection\Definition; + use Symfony\Component\ExpressionLanguage\Expression; + + $container->setDefinition('my_mailer', new Definition( + 'Acme\HelloBundle\Mailer', + array(new Expression('service("mailer_configuration").getMailerMethod()')) + )); + +To learn more about the expression language syntax, see :doc:`/components/expression_language/syntax`. + +In this context, you have access to 2 functions: + +* ``service`` - returns a given service (see the example above); +* ``parameter`` - returns a specific parameter value (syntax is just like ``service``) + +You also have access to the :class:`Symfony\\Component\\DependencyInjection\\ContainerBuilder` +via a ``container`` variable. Here's another example: + +.. configuration-block:: + + .. code-block:: yaml + + services: + my_mailer: + class: Acme\HelloBundle\Mailer + arguments: ["@=container.hasParameter('some_param') ? parameter('some_param') : 'default_value'"] + + .. code-block:: xml + + + + + + + @=container.hasParameter('some_param') ? parameter('some_param') : 'default_value' + + + + + .. code-block:: php + + use Symfony\Component\DependencyInjection\Definition; + use Symfony\Component\ExpressionLanguage\Expression; + + $container->setDefinition('my_mailer', new Definition( + 'Acme\HelloBundle\Mailer', + array(new Expression( + "@=container.hasParameter('some_param') ? parameter('some_param') : 'default_value'" + )) + )); + +Expressions can be used in ``parameters``, ``arguments``, ``properties``, +as arguments with ``configurator`` and as arguments to ``calls`` (method calls). + Optional Dependencies: Setter Injection ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~