|
| 1 | +.. index:: |
| 2 | + single: DependencyInjection; Service definitions |
| 3 | + |
| 4 | +Working with Container Service Definitions |
| 5 | +========================================== |
| 6 | + |
| 7 | +Service definitions are the instructions describing how the container should |
| 8 | +build a service. They are not the actual services used by your applications |
| 9 | + |
| 10 | +Getting and Setting Service Definitions |
| 11 | +--------------------------------------- |
| 12 | + |
| 13 | +There are some helpful methods for working with the service definitions:: |
| 14 | + |
| 15 | +To find out if there is a definition for a service id:: |
| 16 | + |
| 17 | + // find out if there is an "app.mailer" definition |
| 18 | + $container->hasDefinition('app.mailer'); |
| 19 | + // find out if there is an "app.mailer" definition or alias |
| 20 | + $container->has('app.mailer'); |
| 21 | + |
| 22 | + // get the "app.user_config_manager" definition |
| 23 | + $definition = $container->getDefinition('app.user_config_manager'); |
| 24 | + // get the definition with the "app.user_config_manager" ID or alias |
| 25 | + $definition = $container->findDefinition($serviceId); |
| 26 | + |
| 27 | + // add a new "app.number_generator" definitions |
| 28 | + $definition = new Definition('AppBundle\NumberGenerator'); |
| 29 | + $container->setDefinition('app.number_generator', $definition); |
| 30 | + |
| 31 | + // shortcut for the previous method |
| 32 | + $container->register('app.number_generator', 'AppBundle\NumberGenerator'); |
| 33 | + |
| 34 | +Working with a Definition |
| 35 | +------------------------- |
| 36 | + |
| 37 | +Creating a New Definition |
| 38 | +~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 39 | + |
| 40 | +In addition to manipulating and retrieving existing definitions, you can also |
| 41 | +define new service definitions with the :class:`Symfony\\Component\\DependencyInjection\\Definition` |
| 42 | +class. |
| 43 | + |
| 44 | +Class |
| 45 | +~~~~~ |
| 46 | + |
| 47 | +The first optional argument of the ``Definition`` class is the fully qualified |
| 48 | +class name of the object returned when the service is fetched from the container:: |
| 49 | + |
| 50 | + use Symfony\Component\DependencyInjection\Definition; |
| 51 | + |
| 52 | + $definition = new Definition('AppBundle\Config\UserConfigManager'); |
| 53 | + |
| 54 | + // override the class |
| 55 | + $definition->setClass('AppBundle\Config\CustomConfigManager'); |
| 56 | + |
| 57 | + // get the class configured for this definition |
| 58 | + $class = $definition->getClass(); |
| 59 | + |
| 60 | +Constructor Arguments |
| 61 | +~~~~~~~~~~~~~~~~~~~~~ |
| 62 | + |
| 63 | +The second optional argument of the ``Definition`` class is an array with the |
| 64 | +arguments passed to the constructor of the object returned when the service is |
| 65 | +fetched from the container:: |
| 66 | + |
| 67 | + use Symfony\Component\DependencyInjection\Definition; |
| 68 | + |
| 69 | + $definition = new Definition('AppBundle\Config\DoctrineConfigManager', array( |
| 70 | + new Reference('doctrine'), // a reference to another service |
| 71 | + '%app.config_table_name%' // will be resolved to the value of a container parameter |
| 72 | + )); |
| 73 | + |
| 74 | + // get all arguments configured for this definition |
| 75 | + $constructorArguments = $definition->getArguments(); |
| 76 | + |
| 77 | + // get a specific argument |
| 78 | + $firstArgument = $definition->getArgument(0); |
| 79 | + |
| 80 | + // add a new argument |
| 81 | + $definition->addArgument($argument); |
| 82 | + |
| 83 | + // replace argument on a specific index (0 = first argument) |
| 84 | + $definition->replaceArgument($index, $argument); |
| 85 | + |
| 86 | + // replace all previously configured arguments with the passed array |
| 87 | + $definition->setArguments($arguments); |
| 88 | + |
| 89 | +.. caution:: |
| 90 | + |
| 91 | + Don't use ``get()`` to get a service that you want to inject as constructor |
| 92 | + argument, the service is not yet availabe. Instead, use inject a |
| 93 | + ``Reference`` instance as shown above. |
| 94 | + |
| 95 | +Method Calls |
| 96 | +~~~~~~~~~~~~ |
| 97 | + |
| 98 | +If the service you are working with uses setter injection then you can manipulate |
| 99 | +any method calls in the definitions as well:: |
| 100 | + |
| 101 | + // get all configured method calls |
| 102 | + $methodCalls = $definition->getMethodCalls(); |
| 103 | + |
| 104 | + // configure a new method call |
| 105 | + $definition->addMethodCall('setLogger', array(new Reference('logger'))); |
| 106 | + |
| 107 | + // replace all previously configured method calls with the passed array |
| 108 | + $definition->setMethodCalls($methodCalls); |
| 109 | + |
| 110 | +.. tip:: |
| 111 | + |
| 112 | + There are more examples of specific ways of working with definitions |
| 113 | + in the PHP code blocks of the Service Container articles such as |
| 114 | + :doc:`/components/dependency_injection/factories` and |
| 115 | + :doc:`/components/dependency_injection/parentservices`. |
| 116 | + |
| 117 | +.. note:: |
| 118 | + |
| 119 | + The methods here that change service definitions can only be used before |
| 120 | + the container is compiled. Once the container is compiled you cannot |
| 121 | + manipulate service definitions further. To learn more about compiling |
| 122 | + the container, see :doc:`/components/dependency_injection/compilation`. |
| 123 | + |
| 124 | +Requiring Files |
| 125 | +~~~~~~~~~~~~~~~ |
| 126 | + |
| 127 | +There might be use cases when you need to include another file just before |
| 128 | +the service itself gets loaded. To do so, you can use the |
| 129 | +:method:`Symfony\\Component\\DependencyInjection\\Definition::setFile` method:: |
| 130 | + |
| 131 | + $definition->setFile('/src/path/to/file/foo.php'); |
| 132 | + |
| 133 | +Notice that Symfony will internally call the PHP statement ``require_once``, |
| 134 | +which means that your file will be included only once per request. |
0 commit comments