adds synthetic attribute to definitions

This attribute can be used to hint that the service is being injected
dynamically at runtime, and not constructed by the DIC.
This commit is contained in:
Johannes M. Schmitt 2011-01-23 12:06:23 +01:00 committed by Fabien Potencier
parent 7e2331fabd
commit 0144dd86da
7 changed files with 64 additions and 16 deletions

View File

@ -35,7 +35,7 @@
This service definition only defines the scope of the request.
It is used to check references scope.
-->
<service id="request" scope="request" />
<service id="request" scope="request" synthetic="true" />
<service id="response" class="%response.class%" scope="prototype">
<call method="setCharset">

View File

@ -28,6 +28,7 @@ class Definition
protected $configurator;
protected $tags;
protected $public;
protected $synthetic;
/**
* Constructor.
@ -43,6 +44,7 @@ class Definition
$this->scope = ContainerInterface::SCOPE_CONTAINER;
$this->tags = array();
$this->public = true;
$this->synthetic = false;
}
/**
@ -377,6 +379,32 @@ class Definition
return $this->public;
}
/**
* Sets whether this definition is synthetic, that is not constructed by the
* container, but dynamically injected.
*
* @param Boolean $boolean
*
* @return Definition the current instance
*/
public function setSynthetic($boolean)
{
$this->synthetic = (Boolean) $boolean;
return $this;
}
/**
* Whether this definition is synthetic, that is not constructed by the
* container, but dynamically injected.
*
* @return Boolean
*/
public function isSynthetic()
{
return $this->synthetic;
}
/**
* Sets a configurator to call after the service is fully initialized.
*

View File

@ -394,7 +394,9 @@ EOF;
$this->variableCount = 0;
$return = '';
if ($class = $definition->getClass()) {
if ($definition->isSynthetic()) {
$return = sprintf('@throws \RuntimeException always since this service is expected to be injected dynamically');
} else if ($class = $definition->getClass()) {
$return = sprintf("@return %s A %s instance.", 0 === strpos($class, '%') ? 'Object' : $class, $class);
} elseif ($definition->getFactoryService()) {
$return = sprintf('@return Object An instance returned by %s::%s().', $definition->getFactoryService(), $definition->getFactoryMethod());
@ -443,16 +445,20 @@ EOF;
EOF;
}
$code .=
$this->addServiceInclude($id, $definition).
$this->addServiceLocalTempVariables($id, $definition).
$this->addServiceInlinedDefinitions($id, $definition).
$this->addServiceInstance($id, $definition).
$this->addServiceInlinedDefinitionsSetup($id, $definition).
$this->addServiceMethodCalls($id, $definition).
$this->addServiceConfigurator($id, $definition).
$this->addServiceReturn($id, $definition)
;
if ($definition->isSynthetic()) {
$code .= sprintf(" throw new \RuntimeException('You have requested a synthetic service (\"%s\"). The DIC does not know how to construct this service.');\n }\n", $id);
} else {
$code .=
$this->addServiceInclude($id, $definition).
$this->addServiceLocalTempVariables($id, $definition).
$this->addServiceInlinedDefinitions($id, $definition).
$this->addServiceInstance($id, $definition).
$this->addServiceInlinedDefinitionsSetup($id, $definition).
$this->addServiceMethodCalls($id, $definition).
$this->addServiceConfigurator($id, $definition).
$this->addServiceReturn($id, $definition)
;
}
$this->definitionVariables = null;
$this->referenceVariables = null;

View File

@ -12,9 +12,7 @@
namespace Symfony\Component\DependencyInjection\Loader;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\InterfaceInjector;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;
@ -139,7 +137,7 @@ class XmlFileLoader extends FileLoader
$definition = new Definition();
foreach (array('class', 'scope', 'public', 'factory-method', 'factory-service') as $key) {
foreach (array('class', 'scope', 'public', 'factory-method', 'factory-service', 'synthetic') as $key) {
if (isset($service[$key])) {
$method = 'set'.str_replace('-', '', $key);
$definition->$method((string) $service->getAttributeAsPhp($key));

View File

@ -12,7 +12,6 @@
namespace Symfony\Component\DependencyInjection\Loader;
use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\InterfaceInjector;
use Symfony\Component\DependencyInjection\Definition;
@ -148,6 +147,10 @@ class YamlFileLoader extends FileLoader
$definition->setScope($service['scope']);
}
if (isset($service['synthetic'])) {
$definition->setSynthetic($service['synthetic']);
}
if (isset($service['public'])) {
$definition->setPublic($service['public']);
}

View File

@ -103,6 +103,7 @@
<xsd:attribute name="class" type="xsd:string" />
<xsd:attribute name="scope" type="xsd:string" />
<xsd:attribute name="public" type="boolean" />
<xsd:attribute name="synthetic" type="boolean" />
<xsd:attribute name="factory-method" type="xsd:string" />
<xsd:attribute name="factory-service" type="xsd:string" />
<xsd:attribute name="alias" type="xsd:string" />

View File

@ -125,6 +125,18 @@ class DefinitionTest extends \PHPUnit_Framework_TestCase
$this->assertFalse($def->isPublic(), '->isPublic() returns false if the instance must not be public.');
}
/**
* @covers Symfony\Component\DependencyInjection\Definition::setSynthetic
* @covers Symfony\Component\DependencyInjection\Definition::isSynthetic
*/
public function testSetIsSynthetic()
{
$def = new Definition('stdClass');
$this->assertFalse($def->isSynthetic(), '->isSynthetic() returns false by default');
$this->assertSame($def, $def->setSynthetic(true), '->setSynthetic() implements a fluent interface');
$this->assertTrue($def->isSynthetic(), '->isSynthetic() returns true if the instance must not be public.');
}
/**
* @covers Symfony\Component\DependencyInjection\Definition::setConfigurator
* @covers Symfony\Component\DependencyInjection\Definition::getConfigurator