updated documentation for synchronized services #2343

Merged
merged 1 commit into from Mar 26, 2013

Conversation

Projects
None yet
5 participants
Owner

fabpot commented Mar 23, 2013

Q A
Doc fix? no
New docs? yes (symfony/symfony#7007 and symfony/symfony#7457)
Applies to 2.3
Fixed tickets n/a
Owner

fabpot commented Mar 23, 2013

I've updated the documentation by keeping the three possible ways to deal with scoped services, even if I think that the new way (using setter injection) should probably be always used. I've emphasized that in the text, but I don't know if we can do better.

cookbook/service_container/scopes.rst
+If you don't specify the scope, it defaults to ``container``, which is what
+you want most of the time. Unless your service depends on another service
+that's scoped to a narrower scope, you probably don't need to set the scope.
+-------
@wouterj

wouterj Mar 23, 2013

Member

I have never seen this syntax? Is it a typo or is it something I don't know from sphinx?

@fabpot

fabpot Mar 23, 2013

Owner

oops, that's a leftover that I've removed now. Thanks.

cookbook/service_container/scopes.rst
-The scope of a service is set in the definition of the service:
+* Use setter injection if the dependency is "synchronized" (this is the best
+ solution for the ``request`` instance as it is synchronized with the
+ ``request`` scope).
@wouterj

wouterj Mar 23, 2013

Member

I think it will be a great if you put a reference link to each heading below in this list

@fabpot

fabpot Mar 23, 2013

Owner

Good idea. Done.

cookbook/service_container/scopes.rst
@@ -83,12 +105,14 @@ The scope of a service is set in the definition of the service:
greeting_card_manager:
class: Acme\HelloBundle\Mail\GreetingCardManager
scope: request
+ arguments: [@request]
.. code-block:: xml
<!-- src/Acme/HelloBundle/Resources/config/services.xml -->
<services>
<service id="greeting_card_manager" class="Acme\HelloBundle\Mail\GreetingCardManager" scope="request" />
@wouterj

wouterj Mar 23, 2013

Member

While it is not your fault, I prefer to do it like this: (to avoid horizontal scrollbars)

<service id="greeting_card_manager"
    class="Acme\HelloBundle\Mail\GreetingCardManager"
    scope="request"
/>
cookbook/service_container/scopes.rst
+.. tip::
If you define a controller as a service then you can get the ``Request`` object
without injecting the container by having it passed in as an argument of your
action method. See :ref:`book-controller-request-argument` for details.
@wouterj

wouterj Mar 23, 2013

Member

If this is a tip, it should get indented

cookbook/service_container/scopes.rst
+ 'greeting_card_manager',
+ new Definition('Acme\HelloBundle\Mail\GreetingCardManager')
+ )
+ ->addMethodCall('setRequest', array(new Reference('request', ContainerInterface::NULL_ON_INVALID_REFERENCE, false)));
@wouterj

wouterj Mar 23, 2013

Member

I prefer some line breaking in this line too

cookbook/service_container/scopes.rst
+
+.. tip::
+
+ You can declare your own ```synchonized`` services very easily; here is
@wouterj

wouterj Mar 23, 2013

Member

typo: an extra backtick

Member

wouterj commented Mar 23, 2013

@fabpot I think it is a good practise to put the most recommend practise as first. People don't like reading and they will almost always use the first option.

Owner

fabpot commented Mar 23, 2013

@wouterj Not sure about that. That's also why I've first listed the 3 possibilities with short sentences and moved the discussions into their own sections. That way, people are aware of all possibilities and their pros and cons. If I put the best option first, then, why not removing the other two possibilities altogether as nobody cares anymore?

fabpot added a commit to symfony/symfony that referenced this pull request Mar 23, 2013

merged branch fabpot/request-scope (PR #7457)
This PR was merged into the master branch.

Discussion
----------

moved the request scope creation to the ContainerAwareHttpKernel class

| Q             | A
| ------------- | ---
| Bug fix?      | no
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | n/a
| License       | MIT
| Doc PR        | symfony/symfony-docs#2343

While updating the scope documentation, I realized that the request scope was created in the FrameworkBundle while the HttpKernel that manages it was in the HttpKernel component. So, this PR makes things more consistent.

Commits
-------

cec98c1 [DependencyInjection] fixed PHP notice when the scope is not defined
550df5a moved the request scope creation to the ContainerAwareHttpKernel class

fabpot added a commit to symfony/symfony that referenced this pull request Mar 23, 2013

merged branch fabpot/contagious-services (PR #7007)
This PR was merged into the master branch.

Discussion
----------

[2.3] [WIP] Synchronized services...

| Q             | A
| ------------- | ---
| Bug fix?      | no
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #5300, #6756
| License       | MIT
| Doc PR        | symfony/symfony-docs#2343

Todo:

 - [x] update documentation
 - [x] find a better name than contagious (synchronized)?

refs #6932, refs #5012

This PR is a proof of concept that tries to find a solution for some problems we have with scopes and services depending on scoped services (mostly the request service in Symfony).

Basically, whenever you want to inject the Request into a service, you have two possibilities:

 * put your own service into the request scope (a new service will be created whenever a sub-request is run, and the service is not available outside the request scope);

 * set the request service reference as non-strict (your service is always available but the request you have depends on when the service is created the first time).

This PR addresses this issue by allowing to use the second option but you service still always has the right Request service (see below for a longer explanation on how it works).

There is another issue that this PR fixes: edge cases and weird behaviors. There are several bug reports about some weird behaviors, and most of the time, this is related to the sub-requests. That's because the Request is injected into several Symfony objects without being updated correctly when leaving the request scope. Let me explain that: when a listener for instance needs the Request object, it can listen to the `kernel.request` event and store the request somewhere. So, whenever you enter a sub-request, the listener will get the new one. But when the sub-request ends, the listener has no way to know that it needs to reset the request to the master one. In practice, that's not really an issue, but let me show you an example of this issue in practice:

 * You have a controller that is called with the English locale;
 * The controller (probably via a template) renders a sub-request that uses the French locale;
 *  After the rendering, and from the controller, you try to generate a URL. Which locale the router will use? Yes, the French locale, which is wrong.

To fix these issues, this PR introduces a new notion in the DIC: synchronized services. When a service is marked as synchronized, all method calls involving this service will be called each time this service is set. When in a scope, methods are also called to restore the previous version of the service when the scope leaves.

If you have a look at the router or the locale listener, you will see that there is now a `setRequest` method that will called whenever the request service changes (because the `Container::set()` method is called or because the service is changed by a scope change).

Commits
-------

17269e1 [DependencyInjection] fixed management of scoped services with an invalid behavior set to null
bb83b3e [HttpKernel] added a safeguard for when a fragment is rendered outside the context of a master request
5d7b835 [FrameworkBundle] added some functional tests
ff9d688 fixed Request management for FragmentHandler
1b98ad3 fixed Request management for LocaleListener
a7b2b7e fixed Request management for RequestListener
0892135 [HttpKernel] ensured that the Request is null when outside of the Request scope
2ffcfb9 [FrameworkBundle] made the Request service synchronized
ec1e7ca [DependencyInjection] added a way to automatically update scoped services

fabpot added a commit to symfony/framework-bundle that referenced this pull request Mar 25, 2013

merged branch fabpot/request-scope (PR #7457)
This PR was merged into the master branch.

Discussion
----------

moved the request scope creation to the ContainerAwareHttpKernel class

| Q             | A
| ------------- | ---
| Bug fix?      | no
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | n/a
| License       | MIT
| Doc PR        | symfony/symfony-docs#2343

While updating the scope documentation, I realized that the request scope was created in the FrameworkBundle while the HttpKernel that manages it was in the HttpKernel component. So, this PR makes things more consistent.

Commits
-------

cec98c1 [DependencyInjection] fixed PHP notice when the scope is not defined
550df5a moved the request scope creation to the ContainerAwareHttpKernel class

fabpot added a commit to symfony/framework-bundle that referenced this pull request Mar 25, 2013

merged branch fabpot/contagious-services (PR #7007)
This PR was merged into the master branch.

Discussion
----------

[2.3] [WIP] Synchronized services...

| Q             | A
| ------------- | ---
| Bug fix?      | no
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #5300, #6756
| License       | MIT
| Doc PR        | symfony/symfony-docs#2343

Todo:

 - [x] update documentation
 - [x] find a better name than contagious (synchronized)?

refs #6932, refs #5012

This PR is a proof of concept that tries to find a solution for some problems we have with scopes and services depending on scoped services (mostly the request service in Symfony).

Basically, whenever you want to inject the Request into a service, you have two possibilities:

 * put your own service into the request scope (a new service will be created whenever a sub-request is run, and the service is not available outside the request scope);

 * set the request service reference as non-strict (your service is always available but the request you have depends on when the service is created the first time).

This PR addresses this issue by allowing to use the second option but you service still always has the right Request service (see below for a longer explanation on how it works).

There is another issue that this PR fixes: edge cases and weird behaviors. There are several bug reports about some weird behaviors, and most of the time, this is related to the sub-requests. That's because the Request is injected into several Symfony objects without being updated correctly when leaving the request scope. Let me explain that: when a listener for instance needs the Request object, it can listen to the `kernel.request` event and store the request somewhere. So, whenever you enter a sub-request, the listener will get the new one. But when the sub-request ends, the listener has no way to know that it needs to reset the request to the master one. In practice, that's not really an issue, but let me show you an example of this issue in practice:

 * You have a controller that is called with the English locale;
 * The controller (probably via a template) renders a sub-request that uses the French locale;
 *  After the rendering, and from the controller, you try to generate a URL. Which locale the router will use? Yes, the French locale, which is wrong.

To fix these issues, this PR introduces a new notion in the DIC: synchronized services. When a service is marked as synchronized, all method calls involving this service will be called each time this service is set. When in a scope, methods are also called to restore the previous version of the service when the scope leaves.

If you have a look at the router or the locale listener, you will see that there is now a `setRequest` method that will called whenever the request service changes (because the `Container::set()` method is called or because the service is changed by a scope change).

Commits
-------

17269e1 [DependencyInjection] fixed management of scoped services with an invalid behavior set to null
bb83b3e [HttpKernel] added a safeguard for when a fragment is rendered outside the context of a master request
5d7b835 [FrameworkBundle] added some functional tests
ff9d688 fixed Request management for FragmentHandler
1b98ad3 fixed Request management for LocaleListener
a7b2b7e fixed Request management for RequestListener
0892135 [HttpKernel] ensured that the Request is null when outside of the Request scope
2ffcfb9 [FrameworkBundle] made the Request service synchronized
ec1e7ca [DependencyInjection] added a way to automatically update scoped services

fabpot added a commit to symfony/http-kernel that referenced this pull request Mar 25, 2013

merged branch fabpot/request-scope (PR #7457)
This PR was merged into the master branch.

Discussion
----------

moved the request scope creation to the ContainerAwareHttpKernel class

| Q             | A
| ------------- | ---
| Bug fix?      | no
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | n/a
| License       | MIT
| Doc PR        | symfony/symfony-docs#2343

While updating the scope documentation, I realized that the request scope was created in the FrameworkBundle while the HttpKernel that manages it was in the HttpKernel component. So, this PR makes things more consistent.

Commits
-------

cec98c1 [DependencyInjection] fixed PHP notice when the scope is not defined
550df5a moved the request scope creation to the ContainerAwareHttpKernel class

fabpot added a commit to symfony/http-kernel that referenced this pull request Mar 25, 2013

merged branch fabpot/contagious-services (PR #7007)
This PR was merged into the master branch.

Discussion
----------

[2.3] [WIP] Synchronized services...

| Q             | A
| ------------- | ---
| Bug fix?      | no
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #5300, #6756
| License       | MIT
| Doc PR        | symfony/symfony-docs#2343

Todo:

 - [x] update documentation
 - [x] find a better name than contagious (synchronized)?

refs #6932, refs #5012

This PR is a proof of concept that tries to find a solution for some problems we have with scopes and services depending on scoped services (mostly the request service in Symfony).

Basically, whenever you want to inject the Request into a service, you have two possibilities:

 * put your own service into the request scope (a new service will be created whenever a sub-request is run, and the service is not available outside the request scope);

 * set the request service reference as non-strict (your service is always available but the request you have depends on when the service is created the first time).

This PR addresses this issue by allowing to use the second option but you service still always has the right Request service (see below for a longer explanation on how it works).

There is another issue that this PR fixes: edge cases and weird behaviors. There are several bug reports about some weird behaviors, and most of the time, this is related to the sub-requests. That's because the Request is injected into several Symfony objects without being updated correctly when leaving the request scope. Let me explain that: when a listener for instance needs the Request object, it can listen to the `kernel.request` event and store the request somewhere. So, whenever you enter a sub-request, the listener will get the new one. But when the sub-request ends, the listener has no way to know that it needs to reset the request to the master one. In practice, that's not really an issue, but let me show you an example of this issue in practice:

 * You have a controller that is called with the English locale;
 * The controller (probably via a template) renders a sub-request that uses the French locale;
 *  After the rendering, and from the controller, you try to generate a URL. Which locale the router will use? Yes, the French locale, which is wrong.

To fix these issues, this PR introduces a new notion in the DIC: synchronized services. When a service is marked as synchronized, all method calls involving this service will be called each time this service is set. When in a scope, methods are also called to restore the previous version of the service when the scope leaves.

If you have a look at the router or the locale listener, you will see that there is now a `setRequest` method that will called whenever the request service changes (because the `Container::set()` method is called or because the service is changed by a scope change).

Commits
-------

17269e1 [DependencyInjection] fixed management of scoped services with an invalid behavior set to null
bb83b3e [HttpKernel] added a safeguard for when a fragment is rendered outside the context of a master request
5d7b835 [FrameworkBundle] added some functional tests
ff9d688 fixed Request management for FragmentHandler
1b98ad3 fixed Request management for LocaleListener
a7b2b7e fixed Request management for RequestListener
0892135 [HttpKernel] ensured that the Request is null when outside of the Request scope
2ffcfb9 [FrameworkBundle] made the Request service synchronized
ec1e7ca [DependencyInjection] added a way to automatically update scoped services
cookbook/service_container/scopes.rst
+ greeting_card_manager:
+ class: Acme\HelloBundle\Mail\GreetingCardManager
+ calls:
+ - [setRequest, ['@?request']]
@stof

stof Mar 26, 2013

Member

this is not equivalent to the XML format. There is no on-invalid="null" (which cannot be set in YAML btw contrary to on-invalid="ignore")

@fabpot

fabpot Mar 26, 2013

Owner

But it works the exact same way in this case.

cookbook/service_container/scopes.rst
+
+.. tip::
+
+ You can declare your own ``synchonized`` services very easily; here is the
@stof

stof Mar 26, 2013

Member

typo. missing r in synchronized

Contributor

richardmiller commented Mar 26, 2013

@fabpot SInce the new synchronized services are a much better solution than the other two I am inclined to agree with @wouterj that this should be given first and that the other two should be discussed as alternatives afterwards. With it explicitly saying they are worse solutions but that they are documented for historical reasons since they were the available solutions prior to the introduction of synchronized services.

Should there be a note block to say that this is new to 2.3 as well?

Member

wouterj commented Mar 26, 2013

I think we should also create a PR which includes the other options for the older branches.

Owner

fabpot commented Mar 26, 2013

I've updated the docs to put the recommended solution first. Should be ready to merge now.

weaverryan added a commit that referenced this pull request Mar 26, 2013

Merge pull request #2343 from fabpot/synchronized-services
updated documentation for synchronized services

@weaverryan weaverryan merged commit 2821a55 into symfony:master Mar 26, 2013

@@ -82,42 +145,117 @@ The scope of a service is set in the definition of the service:
services:
greeting_card_manager:
class: Acme\HelloBundle\Mail\GreetingCardManager
- scope: request
+ calls:
+ - [setRequest, ['@?request']]
@stof

stof Mar 26, 2013

Member

shouldn't this be '@?request=' to have both on-invalid="ignore" and strict="false" ?

fabpot added a commit to symfony/dependency-injection that referenced this pull request Apr 2, 2013

merged branch fabpot/contagious-services (PR #7007)
This PR was merged into the master branch.

Discussion
----------

[2.3] [WIP] Synchronized services...

| Q             | A
| ------------- | ---
| Bug fix?      | no
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #5300, #6756
| License       | MIT
| Doc PR        | symfony/symfony-docs#2343

Todo:

 - [x] update documentation
 - [x] find a better name than contagious (synchronized)?

refs #6932, refs #5012

This PR is a proof of concept that tries to find a solution for some problems we have with scopes and services depending on scoped services (mostly the request service in Symfony).

Basically, whenever you want to inject the Request into a service, you have two possibilities:

 * put your own service into the request scope (a new service will be created whenever a sub-request is run, and the service is not available outside the request scope);

 * set the request service reference as non-strict (your service is always available but the request you have depends on when the service is created the first time).

This PR addresses this issue by allowing to use the second option but you service still always has the right Request service (see below for a longer explanation on how it works).

There is another issue that this PR fixes: edge cases and weird behaviors. There are several bug reports about some weird behaviors, and most of the time, this is related to the sub-requests. That's because the Request is injected into several Symfony objects without being updated correctly when leaving the request scope. Let me explain that: when a listener for instance needs the Request object, it can listen to the `kernel.request` event and store the request somewhere. So, whenever you enter a sub-request, the listener will get the new one. But when the sub-request ends, the listener has no way to know that it needs to reset the request to the master one. In practice, that's not really an issue, but let me show you an example of this issue in practice:

 * You have a controller that is called with the English locale;
 * The controller (probably via a template) renders a sub-request that uses the French locale;
 *  After the rendering, and from the controller, you try to generate a URL. Which locale the router will use? Yes, the French locale, which is wrong.

To fix these issues, this PR introduces a new notion in the DIC: synchronized services. When a service is marked as synchronized, all method calls involving this service will be called each time this service is set. When in a scope, methods are also called to restore the previous version of the service when the scope leaves.

If you have a look at the router or the locale listener, you will see that there is now a `setRequest` method that will called whenever the request service changes (because the `Container::set()` method is called or because the service is changed by a scope change).

Commits
-------

17269e1 [DependencyInjection] fixed management of scoped services with an invalid behavior set to null
bb83b3e [HttpKernel] added a safeguard for when a fragment is rendered outside the context of a master request
5d7b835 [FrameworkBundle] added some functional tests
ff9d688 fixed Request management for FragmentHandler
1b98ad3 fixed Request management for LocaleListener
a7b2b7e fixed Request management for RequestListener
0892135 [HttpKernel] ensured that the Request is null when outside of the Request scope
2ffcfb9 [FrameworkBundle] made the Request service synchronized
ec1e7ca [DependencyInjection] added a way to automatically update scoped services

fabpot added a commit to symfony/twig-bridge that referenced this pull request Apr 2, 2013

merged branch fabpot/contagious-services (PR #7007)
This PR was merged into the master branch.

Discussion
----------

[2.3] [WIP] Synchronized services...

| Q             | A
| ------------- | ---
| Bug fix?      | no
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #5300, #6756
| License       | MIT
| Doc PR        | symfony/symfony-docs#2343

Todo:

 - [x] update documentation
 - [x] find a better name than contagious (synchronized)?

refs #6932, refs #5012

This PR is a proof of concept that tries to find a solution for some problems we have with scopes and services depending on scoped services (mostly the request service in Symfony).

Basically, whenever you want to inject the Request into a service, you have two possibilities:

 * put your own service into the request scope (a new service will be created whenever a sub-request is run, and the service is not available outside the request scope);

 * set the request service reference as non-strict (your service is always available but the request you have depends on when the service is created the first time).

This PR addresses this issue by allowing to use the second option but you service still always has the right Request service (see below for a longer explanation on how it works).

There is another issue that this PR fixes: edge cases and weird behaviors. There are several bug reports about some weird behaviors, and most of the time, this is related to the sub-requests. That's because the Request is injected into several Symfony objects without being updated correctly when leaving the request scope. Let me explain that: when a listener for instance needs the Request object, it can listen to the `kernel.request` event and store the request somewhere. So, whenever you enter a sub-request, the listener will get the new one. But when the sub-request ends, the listener has no way to know that it needs to reset the request to the master one. In practice, that's not really an issue, but let me show you an example of this issue in practice:

 * You have a controller that is called with the English locale;
 * The controller (probably via a template) renders a sub-request that uses the French locale;
 *  After the rendering, and from the controller, you try to generate a URL. Which locale the router will use? Yes, the French locale, which is wrong.

To fix these issues, this PR introduces a new notion in the DIC: synchronized services. When a service is marked as synchronized, all method calls involving this service will be called each time this service is set. When in a scope, methods are also called to restore the previous version of the service when the scope leaves.

If you have a look at the router or the locale listener, you will see that there is now a `setRequest` method that will called whenever the request service changes (because the `Container::set()` method is called or because the service is changed by a scope change).

Commits
-------

17269e1 [DependencyInjection] fixed management of scoped services with an invalid behavior set to null
bb83b3e [HttpKernel] added a safeguard for when a fragment is rendered outside the context of a master request
5d7b835 [FrameworkBundle] added some functional tests
ff9d688 fixed Request management for FragmentHandler
1b98ad3 fixed Request management for LocaleListener
a7b2b7e fixed Request management for RequestListener
0892135 [HttpKernel] ensured that the Request is null when outside of the Request scope
2ffcfb9 [FrameworkBundle] made the Request service synchronized
ec1e7ca [DependencyInjection] added a way to automatically update scoped services

fabpot added a commit to symfony/framework-bundle that referenced this pull request Nov 11, 2014

merged branch fabpot/request-scope (PR #7457)
This PR was merged into the master branch.

Discussion
----------

moved the request scope creation to the ContainerAwareHttpKernel class

| Q             | A
| ------------- | ---
| Bug fix?      | no
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | n/a
| License       | MIT
| Doc PR        | symfony/symfony-docs#2343

While updating the scope documentation, I realized that the request scope was created in the FrameworkBundle while the HttpKernel that manages it was in the HttpKernel component. So, this PR makes things more consistent.

Commits
-------

cec98c1 [DependencyInjection] fixed PHP notice when the scope is not defined
550df5a moved the request scope creation to the ContainerAwareHttpKernel class

fabpot added a commit to symfony/framework-bundle that referenced this pull request Nov 11, 2014

merged branch fabpot/contagious-services (PR #7007)
This PR was merged into the master branch.

Discussion
----------

[2.3] [WIP] Synchronized services...

| Q             | A
| ------------- | ---
| Bug fix?      | no
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #5300, #6756
| License       | MIT
| Doc PR        | symfony/symfony-docs#2343

Todo:

 - [x] update documentation
 - [x] find a better name than contagious (synchronized)?

refs #6932, refs #5012

This PR is a proof of concept that tries to find a solution for some problems we have with scopes and services depending on scoped services (mostly the request service in Symfony).

Basically, whenever you want to inject the Request into a service, you have two possibilities:

 * put your own service into the request scope (a new service will be created whenever a sub-request is run, and the service is not available outside the request scope);

 * set the request service reference as non-strict (your service is always available but the request you have depends on when the service is created the first time).

This PR addresses this issue by allowing to use the second option but you service still always has the right Request service (see below for a longer explanation on how it works).

There is another issue that this PR fixes: edge cases and weird behaviors. There are several bug reports about some weird behaviors, and most of the time, this is related to the sub-requests. That's because the Request is injected into several Symfony objects without being updated correctly when leaving the request scope. Let me explain that: when a listener for instance needs the Request object, it can listen to the `kernel.request` event and store the request somewhere. So, whenever you enter a sub-request, the listener will get the new one. But when the sub-request ends, the listener has no way to know that it needs to reset the request to the master one. In practice, that's not really an issue, but let me show you an example of this issue in practice:

 * You have a controller that is called with the English locale;
 * The controller (probably via a template) renders a sub-request that uses the French locale;
 *  After the rendering, and from the controller, you try to generate a URL. Which locale the router will use? Yes, the French locale, which is wrong.

To fix these issues, this PR introduces a new notion in the DIC: synchronized services. When a service is marked as synchronized, all method calls involving this service will be called each time this service is set. When in a scope, methods are also called to restore the previous version of the service when the scope leaves.

If you have a look at the router or the locale listener, you will see that there is now a `setRequest` method that will called whenever the request service changes (because the `Container::set()` method is called or because the service is changed by a scope change).

Commits
-------

17269e1 [DependencyInjection] fixed management of scoped services with an invalid behavior set to null
bb83b3e [HttpKernel] added a safeguard for when a fragment is rendered outside the context of a master request
5d7b835 [FrameworkBundle] added some functional tests
ff9d688 fixed Request management for FragmentHandler
1b98ad3 fixed Request management for LocaleListener
a7b2b7e fixed Request management for RequestListener
0892135 [HttpKernel] ensured that the Request is null when outside of the Request scope
2ffcfb9 [FrameworkBundle] made the Request service synchronized
ec1e7ca [DependencyInjection] added a way to automatically update scoped services
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment