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 1 commit
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
Prev Previous commit
[#4228] Move synthetic services to its own recipe
  • Loading branch information
wouterj committed Jun 7, 2015
commit e3c26031b27addc04f84e6dddcadb5a032d71178
55 changes: 0 additions & 55 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
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