Skip to content

Split advanced container configuration article #5284

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 11, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 0 additions & 96 deletions components/dependency_injection/advanced.rst
Original file line number Diff line number Diff line change
Expand Up @@ -73,61 +73,6 @@ below) to access this service (via the alias).

Services are by default public.

Synthetic Services
------------------

Synthetic services are services that are injected into the container instead
of being created by the container.

For example, if you're using the :doc:`HttpKernel </components/http_kernel/introduction>`
component with the DependencyInjection component, then the ``request``
service is injected in the
:method:`ContainerAwareHttpKernel::handle() <Symfony\\Component\\HttpKernel\\DependencyInjection\\ContainerAwareHttpKernel::handle>`
method when entering the request :doc:`scope </cookbook/service_container/scopes>`.
The class does not exist when there is no request, so it can't be included in
the container configuration. Also, the service should be different for every
subrequest in the application.

To create a synthetic service, set ``synthetic`` to ``true``:

.. configuration-block::

.. code-block:: yaml

services:
request:
synthetic: true

.. code-block:: 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="request" synthetic="true" />
</services>
</container>

.. code-block:: php

use Symfony\Component\DependencyInjection\Definition;

$container
->setDefinition('request', new Definition())
->setSynthetic(true);

As you see, only the ``synthetic`` option is set. All other options are only used
to configure how a service is created by the container. As the service isn't
created by the container, these options are omitted.

Now, you can inject the class by using
:method:`Container::set <Symfony\\Component\\DependencyInjection\\Container::set>`::

// ...
$container->set('request', new MyRequest(...));

Aliasing
--------

Expand Down Expand Up @@ -182,44 +127,3 @@ service by asking for the ``bar`` service like this::
foo:
class: Example\Foo
bar: "@foo"


Requiring Files
---------------

There might be use cases when you need to include another file just before
the service itself gets loaded. To do so, you can use the ``file`` directive.

.. configuration-block::

.. code-block:: yaml

services:
foo:
class: Example\Foo\Bar
file: "%kernel.root_dir%/src/path/to/file/foo.php"

.. code-block:: 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="foo" class="Example\Foo\Bar">
<file>%kernel.root_dir%/src/path/to/file/foo.php</file>
</service>
</services>
</container>

.. code-block:: php

use Symfony\Component\DependencyInjection\Definition;

$definition = new Definition('Example\Foo\Bar');
$definition->setFile('%kernel.root_dir%/src/path/to/file/foo.php');
$container->setDefinition('foo', $definition);

Notice that Symfony will internally call the PHP statement ``require_once``,
which means that your file will be included only once per request.
12 changes: 12 additions & 0 deletions components/dependency_injection/definitions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -125,3 +125,15 @@ You can also replace any existing method calls with an array of new ones with::
the container is compiled. Once the container is compiled you cannot
manipulate service definitions further. To learn more about compiling
the container see :doc:`/components/dependency_injection/compilation`.

Requiring Files
~~~~~~~~~~~~~~~

There might be use cases when you need to include another file just before
the service itself gets loaded. To do so, you can use the
:method:`Symfony\\Component\\DependencyInjection\\Definition::setFile` method::

$definition->setFile('/src/path/to/file/foo.php');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what about showing the other formats too, as done previously ? Otherwise, we are loosing some content

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is something we have to think about. Currently, we only show PHP formats in this article. However, this article in general looks like it should recieve a face-lift. Let's do it in another PR :)


Notice that Symfony will internally call the PHP statement ``require_once``,
which means that your file will be included only once per request.
1 change: 1 addition & 0 deletions components/dependency_injection/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
types
parameters
definitions
synthetic_services
compilation
tags
factories
Expand Down
50 changes: 50 additions & 0 deletions components/dependency_injection/synthetic_services.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
.. index::
single: DependencyInjection; Synthetic Services

How to Inject Instances into the Container
------------------------------------------

When using the container in your application, you sometimes need to inject an
instance instead of configuring the container to create a new instance.

For instance, if you're using the :doc:`HttpKernel </components/http_kernel/introduction>`
component with the DependencyInjection component, then the ``kernel``
service is injected into the container from within the ``Kernel`` class::

// ...
abstract class Kernel implements KernelInterface, TerminableInterface
{
// ...
protected function initializeContainer()
{
// ...
$this->container->set('kernel', $this);

// ...
}
}

The ``kernel`` service is called a synthetic service. This service has to be
configured in the container, so the container knows the service does exist
during compilation (otherwise, services depending on this ``kernel`` service
will get a "service does not exists" error).

In order to do so, you have to use
:method:`Definition::setSynthetic() <Symfony\\Component\\DependencyInjection\\Definition::setSynthetic>`::

use Symfony\Component\DependencyInjectino\Definition;

// synthetic services don't specify a class
$kernelDefinition = new Definition();
$kernelDefinition->setSynthetic(true);

$container->setDefinition('your_service', $kernelDefinition);

Now, you can inject the instance in the container using
:method:`Container::set() <Symfony\\Component\\DependencyInjection\\Container::set>`::

$yourService = new YourObject();
$container->set('your_service', $yourService);

``$container->get('your_service')`` will now return the same instance as
``$yourService``.
1 change: 1 addition & 0 deletions components/map.rst.inc
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
* :doc:`/components/dependency_injection/types`
* :doc:`/components/dependency_injection/parameters`
* :doc:`/components/dependency_injection/definitions`
* :doc:`/components/dependency_injection/synthetic_services`
* :doc:`/components/dependency_injection/compilation`
* :doc:`/components/dependency_injection/tags`
* :doc:`/components/dependency_injection/factories`
Expand Down