diff --git a/components/dependency_injection/definitions.rst b/components/dependency_injection/definitions.rst index bd13b766b43..8fab146806d 100644 --- a/components/dependency_injection/definitions.rst +++ b/components/dependency_injection/definitions.rst @@ -4,6 +4,9 @@ Working with Container Service Definitions ========================================== +Service definitions are the instructions describing how the container should +build a service. They are not the actual services used by your applications + Getting and Setting Service Definitions --------------------------------------- @@ -32,7 +35,17 @@ with these methods and make changes to it these will be reflected in the container. If, however, you are creating a new definition then you can add it to the container using:: - $container->setDefinition($id, $definition); + use Symfony\Component\DependencyInjection\Definition; + + $definition = new Definition('Acme\Service\MyService'); + $container->setDefinition('acme.my_service', $definition); + +.. tip:: + + Registering service definitions is so common that the container provides a + shortcut method called ``register()``:: + + $container->register('acme.my_service', 'Acme\Service\MyService'); Working with a Definition ------------------------- @@ -40,26 +53,50 @@ Working with a Definition Creating a New Definition ~~~~~~~~~~~~~~~~~~~~~~~~~ -If you need to create a new definition rather than manipulate one retrieved -from the container then the definition class is :class:`Symfony\\Component\\DependencyInjection\\Definition`. +In addition to manipulating and retrieving existing definitions, you can also +define new service definitions with the :class:`Symfony\\Component\\DependencyInjection\\Definition` +class. Class ~~~~~ -First up is the class of a definition, this is the class of the object returned -when the service is requested from the container. +The first optional argument of the ``Definition`` class is the fully qualified +class name of the object returned when the service is fetched from the container:: -To find out what class is set for a definition:: + use Symfony\Component\DependencyInjection\Definition; + + $definition = new Definition('Acme\Service\MyService'); + +If the class is unknown when instantiating the ``Definition`` class, use the +``setClass()`` method to set it later:: - $definition->getClass(); + $definition->setClass('Acme\Service\MyService'); -and to set a different class:: +To find out what class is set for a definition:: - $definition->setClass($class); // Fully qualified class name as string + $class = $definition->getClass(); + // $class = 'Acme\Service\MyService' Constructor Arguments ~~~~~~~~~~~~~~~~~~~~~ +The second optional argument of the ``Definition`` class is an array with the +arguments passed to the constructor of the object returned when the service is +fetched from the container:: + + use Symfony\Component\DependencyInjection\Definition; + + $definition = new Definition( + 'Acme\Service\MyService', + array('argument1' => 'value1', 'argument2' => 'value2') + ); + +If the arguments are unknown when instantiating the ``Definition`` class or if +you want to add new arguments, use the ``addArgument()`` method, which adds them +at the end of the arguments array:: + + $definition->addArgument($argument); + To get an array of the constructor arguments for a definition you can use:: $definition->getArguments(); @@ -69,12 +106,16 @@ or to get a single argument by its position:: $definition->getArgument($index); // e.g. $definition->getArgument(0) for the first argument -You can add a new argument to the end of the arguments array using:: +The argument can be a string, an array or a service parameter by using the +``%parameter_name%`` syntax:: - $definition->addArgument($argument); + $definition->addArgument('%kernel_debug%'); -The argument can be a string, an array, a service parameter by using ``%parameter_name%`` -or a service id by using:: +If the argument is another service, don't use the ``get()`` method to fetch it, +because it won't be available when defining services. Instead, use the +:class:`Symfony\\Component\\DependencyInjection\\Reference` class to get a +reference to the service which will be available once the service container is +fully built:: use Symfony\Component\DependencyInjection\Reference; @@ -139,4 +180,3 @@ the service itself gets loaded. To do so, you can use the Notice that Symfony will internally call the PHP statement ``require_once``, which means that your file will be included only once per request. - diff --git a/components/dependency_injection/introduction.rst b/components/dependency_injection/introduction.rst index 42c526652fd..a4ad2e93dac 100644 --- a/components/dependency_injection/introduction.rst +++ b/components/dependency_injection/introduction.rst @@ -104,7 +104,9 @@ like this:: // ... } -Then you can register this as a service as well and pass the ``mailer`` service into it:: +When defining the ``newsletter_manager`` service, the ``mailer`` service does +not exist yet. Use the ``Reference`` class to tell the container to inject the +``mailer`` service when it initializes the newsletter manager:: use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Reference;