[DependencyInjection] deprecated synchronized services

This commit is contained in:
Fabien Potencier 2015-01-06 17:17:37 +01:00
parent 7f8ff501a5
commit 82db9c2e52
29 changed files with 198 additions and 100 deletions

View File

@ -95,6 +95,10 @@ UPGRADE FROM 2.x to 3.0
been removed in favor of `Definition::setFactory()`. Services defined using
YAML or XML use the same syntax as configurators.
* Synchronized services are deprecated and the following methods have been
removed: `ContainerBuilder::synchronize()`, `Definition::isSynchronized()`,
and `Definition::setSynchronized()`.
### EventDispatcher
* The interface `Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcherInterface`

View File

@ -44,11 +44,7 @@ class DeprecationErrorHandler
$class = isset($trace[$i]['object']) ? get_class($trace[$i]['object']) : $trace[$i]['class'];
$method = $trace[$i]['function'];
$type =
0 === strpos($method, 'testLegacy')
|| 0 === strpos($method, 'provideLegacy')
|| strpos($class, '\Legacy')
? 'legacy' : 'remaining';
$type = 0 === strpos($method, 'testLegacy') || 0 === strpos($method, 'provideLegacy') || 0 === strpos($method, 'getLegacy') || strpos($class, '\Legacy') ? 'legacy' : 'remaining';
if ('legacy' === $type && 0 === (error_reporting() & E_USER_DEPRECATED)) {
@++$deprecations[$type]['Silenced']['count'];

View File

@ -215,10 +215,13 @@ class JsonDescriptor extends Descriptor
'public' => $definition->isPublic(),
'synthetic' => $definition->isSynthetic(),
'lazy' => $definition->isLazy(),
'synchronized' => $definition->isSynchronized(),
'abstract' => $definition->isAbstract(),
'file' => $definition->getFile(),
);
if (method_exists($definition, 'isSynchronized')) {
$data['synchronized'] = $definition->isSynchronized();
}
$data['abstract'] = $definition->isAbstract();
$data['file'] = $definition->getFile();
if ($definition->getFactoryClass()) {
$data['factory_class'] = $definition->getFactoryClass();

View File

@ -183,8 +183,13 @@ class MarkdownDescriptor extends Descriptor
."\n".'- Public: '.($definition->isPublic() ? 'yes' : 'no')
."\n".'- Synthetic: '.($definition->isSynthetic() ? 'yes' : 'no')
."\n".'- Lazy: '.($definition->isLazy() ? 'yes' : 'no')
."\n".'- Synchronized: '.($definition->isSynchronized() ? 'yes' : 'no')
."\n".'- Abstract: '.($definition->isAbstract() ? 'yes' : 'no');
;
if (method_exists($definition, 'isSynchronized')) {
$output .= "\n".'- Synchronized: '.($definition->isSynchronized() ? 'yes' : 'no');
}
$output .= "\n".'- Abstract: '.($definition->isAbstract() ? 'yes' : 'no');
if ($definition->getFile()) {
$output .= "\n".'- File: `'.$definition->getFile().'`';

View File

@ -265,7 +265,9 @@ class TextDescriptor extends Descriptor
$description[] = sprintf('<comment>Public</comment> %s', $definition->isPublic() ? 'yes' : 'no');
$description[] = sprintf('<comment>Synthetic</comment> %s', $definition->isSynthetic() ? 'yes' : 'no');
$description[] = sprintf('<comment>Lazy</comment> %s', $definition->isLazy() ? 'yes' : 'no');
$description[] = sprintf('<comment>Synchronized</comment> %s', $definition->isSynchronized() ? 'yes' : 'no');
if (method_exists($definition, 'isSynchronized')) {
$description[] = sprintf('<comment>Synchronized</comment> %s', $definition->isSynchronized() ? 'yes' : 'no');
}
$description[] = sprintf('<comment>Abstract</comment> %s', $definition->isAbstract() ? 'yes' : 'no');
if ($definition->getFile()) {

View File

@ -366,7 +366,9 @@ class XmlDescriptor extends Descriptor
$serviceXML->setAttribute('public', $definition->isPublic() ? 'true' : 'false');
$serviceXML->setAttribute('synthetic', $definition->isSynthetic() ? 'true' : 'false');
$serviceXML->setAttribute('lazy', $definition->isLazy() ? 'true' : 'false');
$serviceXML->setAttribute('synchronized', $definition->isSynchronized() ? 'true' : 'false');
if (method_exists($definition, 'isSynchronized')) {
$serviceXML->setAttribute('synchronized', $definition->isSynchronized(false) ? 'true' : 'false');
}
$serviceXML->setAttribute('abstract', $definition->isAbstract() ? 'true' : 'false');
$serviceXML->setAttribute('file', $definition->getFile());

View File

@ -1,6 +1,11 @@
CHANGELOG
=========
2.7.0
-----
* deprecated synchronized services
2.6.0
-----

View File

@ -412,7 +412,7 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
parent::set($id, $service, $scope);
if (isset($this->obsoleteDefinitions[$id]) && $this->obsoleteDefinitions[$id]->isSynchronized()) {
if (isset($this->obsoleteDefinitions[$id]) && $this->obsoleteDefinitions[$id]->isSynchronized(false)) {
$this->synchronize($id);
}
}
@ -1121,9 +1121,15 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
* service by calling all methods referencing it.
*
* @param string $id A service id
*
* @deprecated since version 2.7, will be removed in 3.0.
*/
private function synchronize($id)
{
if ('request' !== $id) {
trigger_error('The '.__METHOD__.' method is deprecated in version 2.7 and will be removed in version 3.0.', E_USER_DEPRECATED);
}
foreach ($this->definitions as $definitionId => $definition) {
// only check initialized services
if (!$this->initialized($definitionId)) {

View File

@ -661,9 +661,15 @@ class Definition
* @return Definition The current instance
*
* @api
*
* @deprecated since version 2.7, will be removed in 3.0.
*/
public function setSynchronized($boolean)
public function setSynchronized($boolean, $triggerDeprecationError = true)
{
if ($triggerDeprecationError) {
trigger_error('The '.__METHOD__.' method is deprecated in version 2.7 and will be removed in version 3.0.', E_USER_DEPRECATED);
}
$this->synchronized = (bool) $boolean;
return $this;
@ -675,9 +681,15 @@ class Definition
* @return bool
*
* @api
*
* @deprecated since version 2.7, will be removed in 3.0.
*/
public function isSynchronized()
public function isSynchronized($triggerDeprecationError = true)
{
if ($triggerDeprecationError) {
trigger_error('The '.__METHOD__.' method is deprecated in version 2.7 and will be removed in version 3.0.', E_USER_DEPRECATED);
}
return $this->synchronized;
}

View File

@ -695,13 +695,19 @@ EOF;
* @param Definition $definition A Definition instance
*
* @return string|null
*
* @deprecated since version 2.7, will be removed in 3.0.
*/
private function addServiceSynchronizer($id, Definition $definition)
{
if (!$definition->isSynchronized()) {
if (!$definition->isSynchronized(false)) {
return;
}
if ('request' !== $id) {
trigger_error('Synchronized services were deprecated in version 2.7 and won\'t work anymore in 3.0.', E_USER_DEPRECATED);
}
$code = '';
foreach ($this->container->getDefinitions() as $definitionId => $definition) {
foreach ($definition->getMethodCalls() as $call) {

View File

@ -135,7 +135,7 @@ class XmlDumper extends Dumper
if ($definition->isSynthetic()) {
$service->setAttribute('synthetic', 'true');
}
if ($definition->isSynchronized()) {
if ($definition->isSynchronized(false)) {
$service->setAttribute('synchronized', 'true');
}
if ($definition->isLazy()) {

View File

@ -103,7 +103,7 @@ class YamlDumper extends Dumper
$code .= sprintf(" synthetic: true\n");
}
if ($definition->isSynchronized()) {
if ($definition->isSynchronized(false)) {
$code .= sprintf(" synchronized: true\n");
}

View File

@ -145,13 +145,17 @@ class XmlFileLoader extends FileLoader
$definition = new Definition();
}
foreach (array('class', 'scope', 'public', 'factory-class', 'factory-method', 'factory-service', 'synthetic', 'synchronized', 'lazy', 'abstract') as $key) {
foreach (array('class', 'scope', 'public', 'factory-class', 'factory-method', 'factory-service', 'synthetic', 'lazy', 'abstract') as $key) {
if ($value = $service->getAttribute($key)) {
$method = 'set'.str_replace('-', '', $key);
$definition->$method(XmlUtils::phpize($value));
}
}
if ($value = $service->getAttribute('synchronized')) {
$definition->setSynchronized(XmlUtils::phpize($value), 'request' !== $id);
}
if ($files = $this->getChildren($service, 'file')) {
$definition->setFile($files[0]->nodeValue);
}

View File

@ -171,7 +171,7 @@ class YamlFileLoader extends FileLoader
}
if (isset($service['synchronized'])) {
$definition->setSynchronized($service['synchronized']);
$definition->setSynchronized($service['synchronized'], 'request' !== $id);
}
if (isset($service['lazy'])) {

View File

@ -683,8 +683,10 @@ class ContainerBuilderTest extends \PHPUnit_Framework_TestCase
$this->assertEquals($a, $container->get('a'));
}
public function testSetOnSynchronizedService()
public function testLegacySetOnSynchronizedService()
{
$this->iniSet('error_reporting', -1 & ~E_USER_DEPRECATED);
$container = new ContainerBuilder();
$container->register('baz', 'BazClass')
->setSynchronized(true)
@ -700,8 +702,10 @@ class ContainerBuilderTest extends \PHPUnit_Framework_TestCase
$this->assertSame($baz, $container->get('bar')->getBaz());
}
public function testSynchronizedServiceWithScopes()
public function testLegacySynchronizedServiceWithScopes()
{
$this->iniSet('error_reporting', -1 & ~E_USER_DEPRECATED);
$container = new ContainerBuilder();
$container->addScope(new Scope('foo'));
$container->register('baz', 'BazClass')

View File

@ -167,8 +167,10 @@ class DefinitionTest extends \PHPUnit_Framework_TestCase
* @covers Symfony\Component\DependencyInjection\Definition::setSynchronized
* @covers Symfony\Component\DependencyInjection\Definition::isSynchronized
*/
public function testSetIsSynchronized()
public function testLegacySetIsSynchronized()
{
$this->iniSet('error_reporting', -1 & ~E_USER_DEPRECATED);
$def = new Definition('stdClass');
$this->assertFalse($def->isSynchronized(), '->isSynchronized() returns false by default');
$this->assertSame($def, $def->setSynchronized(true), '->setSynchronized() implements a fluent interface');

View File

@ -124,6 +124,15 @@ class PhpDumperTest extends \PHPUnit_Framework_TestCase
}
}
public function testLegacySynchronizedServices()
{
$this->iniSet('error_reporting', -1 & ~E_USER_DEPRECATED);
$container = include self::$fixturesPath.'/containers/container20.php';
$dumper = new PhpDumper($container);
$this->assertEquals(str_replace('%path%', str_replace('\\', '\\\\', self::$fixturesPath.DIRECTORY_SEPARATOR.'includes'.DIRECTORY_SEPARATOR), file_get_contents(self::$fixturesPath.'/php/services20.php')), $dumper->dump(), '->dump() dumps services');
}
public function testServicesWithAnonymousFactories()
{
$container = include self::$fixturesPath.'/containers/container19.php';

View File

@ -0,0 +1,19 @@
<?php
require_once __DIR__.'/../includes/classes.php';
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
$container = new ContainerBuilder();
$container
->register('request', 'Request')
->setSynchronized(true)
;
$container
->register('depends_on_request', 'stdClass')
->addMethodCall('setRequest', array(new Reference('request', ContainerInterface::NULL_ON_INVALID_REFERENCE, false)))
;
return $container;

View File

@ -77,11 +77,6 @@ $container
$container
->register('request', 'Request')
->setSynthetic(true)
->setSynchronized(true)
;
$container
->register('depends_on_request', 'stdClass')
->addMethodCall('setRequest', array(new Reference('request', ContainerInterface::NULL_ON_INVALID_REFERENCE, false)))
;
$container
->register('configurator_service', 'ConfClass')

View File

@ -13,7 +13,6 @@ digraph sc {
node_inlined [label="inlined\nBar\n", shape=record, fillcolor="#eeeeee", style="filled"];
node_baz [label="baz\nBaz\n", shape=record, fillcolor="#eeeeee", style="filled"];
node_request [label="request\nRequest\n", shape=record, fillcolor="#eeeeee", style="filled"];
node_depends_on_request [label="depends_on_request\nstdClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
node_configurator_service [label="configurator_service\nConfClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
node_configured_service [label="configured_service\nstdClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
node_decorated [label="decorated\nstdClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
@ -38,6 +37,5 @@ digraph sc {
node_foo_with_inline -> node_inlined [label="setBar()" style="dashed"];
node_inlined -> node_baz [label="setBaz()" style="dashed"];
node_baz -> node_foo_with_inline [label="setFoo()" style="dashed"];
node_depends_on_request -> node_request [label="setRequest()" style="dashed"];
node_configurator_service -> node_baz [label="setFoo()" style="dashed"];
}

View File

@ -0,0 +1,73 @@
<?php
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\Exception\InactiveScopeException;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\LogicException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
/**
* ProjectServiceContainer
*
* This class has been auto-generated
* by the Symfony Dependency Injection Component.
*/
class ProjectServiceContainer extends Container
{
private $parameters;
private $targetDirs = array();
/**
* Constructor.
*/
public function __construct()
{
parent::__construct();
$this->methodMap = array(
'depends_on_request' => 'getDependsOnRequestService',
'request' => 'getRequestService',
);
}
/**
* Gets the 'depends_on_request' service.
*
* This service is shared.
* This method always returns the same instance of the service.
*
* @return \stdClass A stdClass instance.
*/
protected function getDependsOnRequestService()
{
$this->services['depends_on_request'] = $instance = new \stdClass();
$instance->setRequest($this->get('request', ContainerInterface::NULL_ON_INVALID_REFERENCE));
return $instance;
}
/**
* Gets the 'request' service.
*
* This service is shared.
* This method always returns the same instance of the service.
*
* @return \Request A Request instance.
*/
protected function getRequestService()
{
return $this->services['request'] = new \Request();
}
/**
* Updates the 'request' service.
*/
protected function synchronizeRequestService()
{
if ($this->initialized('depends_on_request')) {
$this->get('depends_on_request')->setRequest($this->get('request', ContainerInterface::NULL_ON_INVALID_REFERENCE));
}
}
}

View File

@ -33,7 +33,6 @@ class ProjectServiceContainer extends Container
'decorated' => 'getDecoratedService',
'decorator_service' => 'getDecoratorServiceService',
'decorator_service_with_name' => 'getDecoratorServiceWithNameService',
'depends_on_request' => 'getDependsOnRequestService',
'factory_service' => 'getFactoryServiceService',
'foo' => 'getFooService',
'foo.baz' => 'getFoo_BazService',
@ -144,23 +143,6 @@ class ProjectServiceContainer extends Container
return $this->services['decorator_service_with_name'] = new \stdClass();
}
/**
* Gets the 'depends_on_request' service.
*
* This service is shared.
* This method always returns the same instance of the service.
*
* @return \stdClass A stdClass instance.
*/
protected function getDependsOnRequestService()
{
$this->services['depends_on_request'] = $instance = new \stdClass();
$instance->setRequest($this->get('request', ContainerInterface::NULL_ON_INVALID_REFERENCE));
return $instance;
}
/**
* Gets the 'factory_service' service.
*
@ -314,16 +296,6 @@ class ProjectServiceContainer extends Container
return $this->services['service_from_static_method'] = \Bar\FooClass::getInstance();
}
/**
* Updates the 'request' service.
*/
protected function synchronizeRequestService()
{
if ($this->initialized('depends_on_request')) {
$this->get('depends_on_request')->setRequest($this->get('request', ContainerInterface::NULL_ON_INVALID_REFERENCE));
}
}
/**
* Gets the 'configurator_service' service.
*

View File

@ -40,7 +40,6 @@ class ProjectServiceContainer extends Container
'configured_service' => 'getConfiguredServiceService',
'decorator_service' => 'getDecoratorServiceService',
'decorator_service_with_name' => 'getDecoratorServiceWithNameService',
'depends_on_request' => 'getDependsOnRequestService',
'factory_service' => 'getFactoryServiceService',
'foo' => 'getFooService',
'foo.baz' => 'getFoo_BazService',
@ -148,23 +147,6 @@ class ProjectServiceContainer extends Container
return $this->services['decorator_service_with_name'] = new \stdClass();
}
/**
* Gets the 'depends_on_request' service.
*
* This service is shared.
* This method always returns the same instance of the service.
*
* @return \stdClass A stdClass instance.
*/
protected function getDependsOnRequestService()
{
$this->services['depends_on_request'] = $instance = new \stdClass();
$instance->setRequest($this->get('request', ContainerInterface::NULL_ON_INVALID_REFERENCE));
return $instance;
}
/**
* Gets the 'factory_service' service.
*
@ -318,16 +300,6 @@ class ProjectServiceContainer extends Container
return $this->services['service_from_static_method'] = \Bar\FooClass::getInstance();
}
/**
* Updates the 'request' service.
*/
protected function synchronizeRequestService()
{
if ($this->initialized('depends_on_request')) {
$this->get('depends_on_request')->setRequest($this->get('request', ContainerInterface::NULL_ON_INVALID_REFERENCE));
}
}
/**
* {@inheritdoc}
*/

View File

@ -0,0 +1,11 @@
<?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" class="Request" synthetic="true" synchronized="true"/>
<service id="depends_on_request" class="stdClass">
<call method="setRequest">
<argument type="service" id="request" on-invalid="null" strict="false"/>
</call>
</service>
</services>
</container>

View File

@ -74,12 +74,7 @@
<argument type="service" id="foo_with_inline"/>
</call>
</service>
<service id="request" class="Request" synthetic="true" synchronized="true"/>
<service id="depends_on_request" class="stdClass">
<call method="setRequest">
<argument type="service" id="request" on-invalid="null" strict="false"/>
</call>
</service>
<service id="request" class="Request" synthetic="true"/>
<service id="configurator_service" class="ConfClass" public="false">
<call method="setFoo">
<argument type="service" id="baz"/>

View File

@ -0,0 +1,9 @@
services:
request:
class: Request
synthetic: true
synchronized: true
depends_on_request:
class: stdClass
calls:
- [setRequest, ['@?request']]

View File

@ -64,12 +64,6 @@ services:
request:
class: Request
synthetic: true
synchronized: true
depends_on_request:
class: stdClass
calls:
- [setRequest, ['@?request']]
configurator_service:
class: ConfClass
public: false

View File

@ -219,7 +219,7 @@ class XmlFileLoaderTest extends \PHPUnit_Framework_TestCase
$this->assertEquals(array('BazClass', 'getInstance'), $services['new_factory3']->getFactory(), '->load() parses the factory tag');
$this->assertTrue($services['request']->isSynthetic(), '->load() parses the synthetic flag');
$this->assertTrue($services['request']->isSynchronized(), '->load() parses the synchronized flag');
$this->assertTrue($services['request']->isSynchronized(false), '->load() parses the synchronized flag');
$this->assertTrue($services['request']->isLazy(), '->load() parses the lazy flag');
$aliases = $container->getAliases();

View File

@ -146,7 +146,7 @@ class YamlFileLoaderTest extends \PHPUnit_Framework_TestCase
$this->assertEquals(array('BazClass', 'getInstance'), $services['new_factory3']->getFactory(), '->load() parses the factory tag');
$this->assertTrue($services['request']->isSynthetic(), '->load() parses the synthetic flag');
$this->assertTrue($services['request']->isSynchronized(), '->load() parses the synchronized flag');
$this->assertTrue($services['request']->isSynchronized(false), '->load() parses the synchronized flag');
$this->assertTrue($services['request']->isLazy(), '->load() parses the lazy flag');
$aliases = $container->getAliases();