removed support for interface injection as well as all relevant tests

This commit is contained in:
Lukas Kahwe Smith 2011-04-23 11:42:31 +02:00
parent b347aebee8
commit d9491a743e
25 changed files with 7 additions and 1141 deletions

View File

@ -58,11 +58,4 @@
<argument>%kernel.root_dir%/Resources</argument>
</service>
</services>
<interfaces>
<interface class="Symfony\Component\DependencyInjection\ContainerAwareInterface">
<call method="setContainer">
<argument type="service" id="service_container" />
</call>
</interface>
</interfaces>
</container>

View File

@ -49,9 +49,8 @@ class CheckDefinitionValidityPass implements CompilerPassInterface
if (!$definition->isAbstract() && !$definition->isSynthetic() && !$definition->getClass()) {
if ($definition->getFactoryClass() || $definition->getFactoryService()) {
throw new \RuntimeException(sprintf(
'Please add the class to service "%s" even if it is constructed '
.'by a factory since we might need to add method calls based on '
.'interface injection, or other compile-time checks.',
'Please add the class to service "%s" even if it is constructed by a factory '
.'since we might need to add method calls based on compile-time checks.',
$id
));
}
@ -66,4 +65,4 @@ class CheckDefinitionValidityPass implements CompilerPassInterface
}
}
}
}
}

View File

@ -49,7 +49,6 @@ class PassConfig
new ResolveParameterPlaceHoldersPass(),
new CheckDefinitionValidityPass(),
new ResolveReferencesToAliasesPass(),
new ResolveInterfaceInjectorsPass(),
new ResolveInvalidReferencesPass(),
new AnalyzeServiceReferencesPass(true),
new CheckCircularReferencesPass(),
@ -224,4 +223,4 @@ class PassConfig
{
$this->removingPasses = $passes;
}
}
}

View File

@ -1,51 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\ContainerBuilder;
/**
* Resolves interface injectors and inlines them as method calls
*
* @author Bulat Shakirzyanov <mallluhuct@gmail.com>
*/
class ResolveInterfaceInjectorsPass implements CompilerPassInterface
{
/**
* {@inheritDoc}
*/
public function process(ContainerBuilder $container)
{
foreach ($container->getDefinitions() as $definition) {
if (!$definition->getClass()) {
continue;
}
$loaded = false;
foreach ($container->getInterfaceInjectors() as $injector) {
if (null !== $definition->getFactoryClass() || null !== $definition->getFactoryService()) {
continue;
}
if (false === $loaded && null !== $definition->getFile()) {
$loaded = true;
require_once $definition->getFile();
}
if ($injector->supports($definition->getClass())) {
$injector->processDefinition($definition);
}
}
}
}
}

View File

@ -51,13 +51,6 @@ class ResolveParameterPlaceHoldersPass implements CompilerPassInterface
}
$container->setAliases($aliases);
$injectors = array();
foreach ($container->getInterfaceInjectors() as $class => $injector) {
$injector->setClass($this->resolveValue($injector->getClass()));
$injectors[$this->resolveValue($class)] = $injector;
}
$container->setInterfaceInjectors($injectors);
$parameterBag = $container->getParameterBag();
foreach ($parameterBag->all() as $key => $value) {
$parameterBag->set($key, $this->resolveValue($value));

View File

@ -15,7 +15,6 @@ use Symfony\Component\DependencyInjection\Compiler\Compiler;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
use Symfony\Component\DependencyInjection\Extension\ExtensionInterface;
use Symfony\Component\DependencyInjection\InterfaceInjector;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\Config\Resource\FileResource;
use Symfony\Component\Config\Resource\ResourceInterface;
@ -341,7 +340,6 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
$this->addDefinitions($container->getDefinitions());
$this->addAliases($container->getAliases());
$this->addInterfaceInjectors($container->getInterfaceInjectors());
$this->getParameterBag()->add($container->getParameterBag()->all());
foreach ($container->getResources() as $resource) {
@ -514,74 +512,6 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
return $this->aliases[$id];
}
/**
* Adds an InterfaceInjector.
*
* @param InterfaceInjector $injector
*/
public function addInterfaceInjector(InterfaceInjector $injector)
{
$class = $injector->getClass();
if (isset($this->injectors[$class])) {
return $this->injectors[$class]->merge($injector);
}
$this->injectors[$class] = $injector;
}
/**
* Adds multiple InterfaceInjectors.
*
* @param array $injectors An array of InterfaceInjectors
*/
public function addInterfaceInjectors(array $injectors)
{
foreach ($injectors as $injector) {
$this->addInterfaceInjector($injector);
}
}
/**
* Gets defined InterfaceInjectors. If a service is provided, only that
* support the service will be returned.
*
* @param string $service If provided, only injectors supporting this service will be returned
*
* @return array An array of InterfaceInjectors
*/
public function getInterfaceInjectors($service = null)
{
if (null === $service) {
return $this->injectors;
}
return array_filter($this->injectors, function(InterfaceInjector $injector) use ($service) {
return $injector->supports($service);
});
}
/**
* Returns true if an InterfaceInjector is defined for the class.
*
* @param string $class The class
*
* @return Boolean true if at least one InterfaceInjector is defined, false otherwise
*/
public function hasInterfaceInjectorForClass($class)
{
return array_key_exists($class, $this->injectors);
}
/**
* Sets the defined InterfaceInjectors.
*
* @param array $injectors An array of InterfaceInjectors indexed by class names
*/
public function setInterfaceInjectors(array $injectors)
{
$this->injectors = $injectors;
}
/**
* Registers a service definition.
*
@ -740,10 +670,6 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
$service = null === $r->getConstructor() ? $r->newInstance() : $r->newInstanceArgs($arguments);
}
foreach ($this->getInterfaceInjectors($service) as $injector) {
$injector->processDefinition($definition, $service);
}
if (self::SCOPE_PROTOTYPE !== $scope = $definition->getScope()) {
if (self::SCOPE_CONTAINER !== $scope && !isset($this->scopedServices[$scope])) {
throw new \RuntimeException('You tried to create a service of an inactive scope.');

View File

@ -86,53 +86,12 @@ class PhpDumper extends Dumper
$code .=
$this->addServices().
$this->addDefaultParametersMethod().
$this->addInterfaceInjectors().
$this->endClass()
;
return $code;
}
/**
* Returns applyInterfaceInjectors function for the dumper.
*
* @return string
*/
private function addInterfaceInjectors()
{
if ($this->container->isFrozen() || 0 === count($this->container->getInterfaceInjectors())) {
return;
}
$code = <<<EOF
/**
* Applies all known interface injection calls
*
* @param Object \$instance
*/
protected function applyInterfaceInjectors(\$instance)
{
EOF;
foreach ($this->container->getInterfaceInjectors() as $injector) {
$code .= sprintf(" if (\$instance instanceof \\%s) {\n", $injector->getClass());
foreach ($injector->getMethodCalls() as $call) {
$arguments = array();
foreach ($call[1] as $value) {
$arguments[] = $this->dumpValue($value);
}
$code .= $this->wrapServiceConditionals($call[1], sprintf(" \$instance->%s(%s);\n", $call[0], implode(', ', $arguments)));
}
$code .= sprintf(" }\n");
}
$code .= <<<EOF
}
EOF;
return $code;
}
/**
* Generates Service local temp variables.
*
@ -375,10 +334,6 @@ EOF;
*/
private function isSimpleInstance($id, $definition)
{
if (!$this->container->isFrozen() && count($this->container->getInterfaceInjectors()) > 0) {
return false;
}
foreach (array_merge(array($definition), $this->getInlinedDefinitions($definition)) as $sDefinition) {
if ($definition !== $sDefinition && !$this->hasReference($id, $sDefinition->getMethodCalls())) {
continue;
@ -412,10 +367,6 @@ EOF;
$calls .= $this->wrapServiceConditionals($call[1], sprintf(" \$%s->%s(%s);\n", $variableName, $call[0], implode(', ', $arguments)));
}
if (!$this->container->isFrozen() && count($this->container->getInterfaceInjectors()) > 0) {
$calls .= sprintf("\n \$this->applyInterfaceInjectors(\$%s);\n", $variableName);
}
return $calls;
}

View File

@ -15,7 +15,6 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Parameter;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\InterfaceInjector;
/**
* XmlDumper dumps a service container as an XML string.
@ -48,7 +47,6 @@ class XmlDumper extends Dumper
$this->addParameters($container);
$this->addServices($container);
$this->addInterfaceInjectors($container);
$this->document->appendChild($container);
$xml = $this->document->saveXML();
@ -98,40 +96,6 @@ class XmlDumper extends Dumper
}
}
/**
* Adds interface injector.
*
* @param InterfaceInjector $injector
* @param DOMElement $parent
* @return void
*/
private function addInterfaceInjector(InterfaceInjector $injector, \DOMElement $parent)
{
$interface = $this->document->createElement('interface');
$interface->setAttribute('class', $injector->getClass());
$this->addMethodCalls($injector->getMethodCalls(), $interface);
$parent->appendChild($interface);
}
/**
* Adds interface injectors.
*
* @param DOMElement $parent
* @return void
*/
private function addInterfaceInjectors(\DOMElement $parent)
{
if (!$this->container->getInterfaceInjectors()) {
return;
}
$interfaces = $this->document->createElement('interfaces');
foreach ($this->container->getInterfaceInjectors() as $injector) {
$this->addInterfaceInjector($injector, $interfaces);
}
$parent->appendChild($interfaces);
}
/**
* Adds a service.
*

View File

@ -32,29 +32,7 @@ class YamlDumper extends Dumper
*/
public function dump(array $options = array())
{
return $this->addParameters().$this->addInterfaceInjectors()."\n".$this->addServices();
}
/**
* Adds interface injectors
*
* @return string
*/
private function addInterfaceInjectors()
{
if (!$this->container->getInterfaceInjectors()) {
return '';
}
$code = "\ninterfaces:\n";
foreach ($this->container->getInterfaceInjectors() as $injector) {
$code .= sprintf(" %s:\n", $injector->getClass());
if ($injector->getMethodCalls()) {
$code .= sprintf(" calls:\n %s\n", str_replace("\n", "\n ", Yaml::dump($this->dumpValue($injector->getMethodCalls()), 1)));
}
}
return $code;
return $this->addParameters()."\n".$this->addServices();
}
/**

View File

@ -1,187 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\DependencyInjection;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
/**
* InterfaceInjector is used for Interface Injection.
*
* @author Bulat Shakirzyanov <mallluhuct@gmail.com>
*/
class InterfaceInjector
{
private $class;
private $calls = array();
private $processedDefinitions = array();
/**
* Constructs interface injector by specifying the target class name
*
* @param string $class
*/
public function __construct($class)
{
$this->class = $class;
}
/**
* Returns the interface name
*
* @return string
*/
public function getClass()
{
return $this->class;
}
/**
* Sets the interface class
*
* @param string $class
* @return void
*/
public function setClass($class)
{
$this->class = $class;
}
/**
* Adds method calls if Definition is of required interface
*
* @param Definition $definition
* @param string $class
* @return void
*/
public function processDefinition(Definition $definition, $class = null)
{
if (in_array($definition, $this->processedDefinitions, true)) {
return;
}
$class = $class ?: $definition->getClass();
if (!$this->supports($class)) {
return;
}
foreach ($this->calls as $callback) {
list($method, $arguments) = $callback;
$definition->addMethodCall($method, $arguments);
}
$this->processedDefinitions[] = $definition;
}
/**
* Inspects if current interface injector is to be used with a given class
*
* @param string $object
* @return Boolean
*/
public function supports($object)
{
if (is_string($object)) {
if (!class_exists($object)) {
return false;
}
$reflection = new \ReflectionClass($object);
return $reflection->isSubClassOf($this->class)
|| $object === $this->class;
}
if ( ! is_object($object)) {
throw new InvalidArgumentException(sprintf("%s expects class or object, %s given", __METHOD__, substr(str_replace("\n", '', var_export($object, true)), 0, 10)));
}
return is_a($object, $this->class);
}
/**
* Adds a method to call to be injected on any service implementing the interface.
*
* @param string $method The method name to call
* @param array $arguments An array of arguments to pass to the method call
*
* @return InterfaceInjector The current instance
*/
public function addMethodCall($method, array $arguments = array())
{
$this->calls[] = array($method, $arguments);
return $this;
}
/**
* Removes a method to call after service initialization.
*
* @param string $method The method name to remove
*
* @return Definition The current instance
*/
public function removeMethodCall($method)
{
foreach ($this->calls as $i => $call) {
if ($call[0] === $method) {
unset($this->calls[$i]);
break;
}
}
return $this;
}
/**
* Check if the current definition has a given method to call after service initialization.
*
* @param string $method The method name to search for
*
* @return Boolean
*/
public function hasMethodCall($method)
{
foreach ($this->calls as $call) {
if ($call[0] === $method) {
return true;
}
}
return false;
}
/**
* Gets the methods to call after service initialization.
*
* @return array An array of method calls
*/
public function getMethodCalls()
{
return $this->calls;
}
/**
* Merges another InterfaceInjector
*
* @param InterfaceInjector $injector
*/
public function merge(InterfaceInjector $injector)
{
if ($this->class === $injector->getClass()) {
foreach ($injector->getMethodCalls() as $call) {
list ($method, $arguments) = $call;
$this->addMethodCall($method, $arguments);
}
}
}
}

View File

@ -15,7 +15,6 @@ use Symfony\Component\DependencyInjection\DefinitionDecorator;
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;
use Symfony\Component\DependencyInjection\ContainerBuilder;
@ -56,9 +55,6 @@ class XmlFileLoader extends FileLoader
// extensions
$this->loadFromExtensions($xml);
// interface injectors
$this->parseInterfaceInjectors($xml, $file);
// services
$this->parseDefinitions($xml, $file);
}
@ -111,40 +107,6 @@ class XmlFileLoader extends FileLoader
}
}
/**
* Parses interface injectors
*
* @param SimpleXMLElement $xml
* @param string $file
* @return void
*/
private function parseInterfaceInjectors(SimpleXMLElement $xml, $file)
{
if (!$xml->interfaces) {
return;
}
foreach ($xml->interfaces->interface as $interface) {
$this->parseInterfaceInjector((string) $interface['class'], $interface, $file);
}
}
/**
* Parses an individual interface injector
*
* @param string $class
* @param SimpleXMLElement $interface
* @param string $file
*/
private function parseInterfaceInjector($class, $interface, $file)
{
$injector = new InterfaceInjector($class);
foreach ($interface->call as $call) {
$injector->addMethodCall((string) $call['method'], $call->getArgumentsAsPhp('argument'));
}
$this->container->addInterfaceInjector($injector);
}
/**
* Parses multiple definitions
*

View File

@ -14,7 +14,6 @@ namespace Symfony\Component\DependencyInjection\Loader;
use Symfony\Component\DependencyInjection\DefinitionDecorator;
use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\InterfaceInjector;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\ContainerBuilder;
@ -62,9 +61,6 @@ class YamlFileLoader extends FileLoader
// extensions
$this->loadFromExtensions($content);
// interface injectors
$this->parseInterfaceInjectors($content, $file);
// services
$this->parseDefinitions($content, $file);
}
@ -101,43 +97,6 @@ class YamlFileLoader extends FileLoader
}
}
/**
* Parses interface injectors.
*
* @param array $content
* @param string $file
* @return void
*/
private function parseInterfaceInjectors($content, $file)
{
if (!isset($content['interfaces'])) {
return;
}
foreach ($content['interfaces'] as $class => $interface) {
$this->parseInterfaceInjector($class, $interface, $file);
}
}
/**
* Parses an interface injector.
*
* @param string $class
* @param array $interface
* @param string $file
* @return void
*/
private function parseInterfaceInjector($class, $interface, $file)
{
$injector = new InterfaceInjector($class);
if (isset($interface['calls'])) {
foreach ($interface['calls'] as $call) {
$injector->addMethodCall($call[0], $this->resolveServices($call[1]));
}
}
$this->container->addInterfaceInjector($injector);
}
/**
* Parses definitions
*
@ -292,7 +251,7 @@ class YamlFileLoader extends FileLoader
}
foreach (array_keys($content) as $namespace) {
if (in_array($namespace, array('imports', 'parameters', 'services', 'interfaces'))) {
if (in_array($namespace, array('imports', 'parameters', 'services'))) {
continue;
}
@ -345,7 +304,7 @@ class YamlFileLoader extends FileLoader
private function loadFromExtensions($content)
{
foreach ($content as $namespace => $values) {
if (in_array($namespace, array('imports', 'parameters', 'services', 'interfaces'))) {
if (in_array($namespace, array('imports', 'parameters', 'services'))) {
continue;
}

View File

@ -28,22 +28,10 @@
<xsd:element name="imports" type="imports" minOccurs="0" maxOccurs="1" />
<xsd:element name="parameters" type="parameters" minOccurs="0" maxOccurs="1" />
<xsd:element name="services" type="services" minOccurs="0" maxOccurs="1" />
<xsd:element name="interfaces" type="interfaces" minOccurs="0" maxOccurs="1" />
<xsd:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="interfaces">
<xsd:annotation>
<xsd:documentation><![CDATA[
Enclosing element for the definition of all interface injectors
]]></xsd:documentation>
</xsd:annotation>
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element name="interface" type="interface" />
</xsd:choice>
</xsd:complexType>
<xsd:complexType name="services">
<xsd:annotation>
<xsd:documentation><![CDATA[
@ -84,13 +72,6 @@
<xsd:attribute name="function" type="xsd:string" />
</xsd:complexType>
<xsd:complexType name="interface">
<xsd:choice minOccurs="1" maxOccurs="unbounded">
<xsd:element name="call" type="call" />
</xsd:choice>
<xsd:attribute name="class" type="xsd:string" use="required" />
</xsd:complexType>
<xsd:complexType name="service">
<xsd:choice maxOccurs="unbounded">
<xsd:element name="file" type="xsd:string" minOccurs="0" maxOccurs="1" />

View File

@ -470,30 +470,6 @@ class ContainerBuilderTest extends \PHPUnit_Framework_TestCase
$container->compile();
}
/**
* @covers Symfony\Component\DependencyInjection\ContainerBuilder::addInterfaceInjector
* @covers Symfony\Component\DependencyInjection\ContainerBuilder::addInterfaceInjectors
* @covers Symfony\Component\DependencyInjection\ContainerBuilder::getInterfaceInjectors
* @covers Symfony\Component\DependencyInjection\ContainerBuilder::hasInterfaceInjectorForClass
* @covers Symfony\Component\DependencyInjection\ContainerBuilder::setDefinition
*/
public function testInterfaceInjection()
{
$definition = new Definition('Symfony\Tests\Component\DependencyInjection\FooClass');
$injectors[] = $this->getMockInterfaceInjector('Symfony\Tests\Component\DependencyInjection\FooClass', 1);
$injectors[] = $this->getMockInterfaceInjector('Symfony\Tests\Component\DependencyInjection\FooClass', 0);
$container = new ContainerBuilder();
$container->addInterfaceInjectors($injectors);
$this->assertEquals(1, count($container->getInterfaceInjectors('Symfony\Tests\Component\DependencyInjection\FooClass')));
$this->assertTrue($container->hasInterfaceInjectorForClass('Symfony\Tests\Component\DependencyInjection\FooClass'));
$this->assertFalse($container->hasInterfaceInjectorForClass('\Foo'));
$container->setDefinition('test', $definition);
$test = $container->get('test');
}
/**
* @expectedException BadMethodCallException
*/
@ -513,20 +489,6 @@ class ContainerBuilderTest extends \PHPUnit_Framework_TestCase
$container->compile();
$container->setDefinition('a', new Definition());
}
/**
* @param string $class
* @param int $methodCallsCount
* @return Symfony\Component\DependencyInjection\InterfaceInjector
*/
private function getMockInterfaceInjector($class, $methodCallsCount)
{
$injector = $this->getMock('Symfony\Component\DependencyInjection\InterfaceInjector', array('processDefinition'), array('Symfony\Tests\Component\DependencyInjection\FooClass'), '', true, false);
$injector->expects($this->exactly($methodCallsCount))
->method('processDefinition')
;
return $injector;
}
}

View File

@ -15,7 +15,6 @@ use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Dumper\PhpDumper;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\InterfaceInjector;
class PhpDumperTest extends \PHPUnit_Framework_TestCase
{
@ -93,41 +92,4 @@ class PhpDumperTest extends \PHPUnit_Framework_TestCase
$this->assertSame($bar, $container->get('foo')->bar, '->set() overrides an already defined service');
}
public function testInterfaceInjectors()
{
$interfaceInjector = new InterfaceInjector('FooClass');
$interfaceInjector->addMethodCall('setBar', array('someValue'));
$container = include self::$fixturesPath.'/containers/interfaces1.php';
$container->addInterfaceInjector($interfaceInjector);
$dumper = new PhpDumper($container);
$this->assertStringEqualsFile(self::$fixturesPath.'/php/services_interfaces-1.php', $dumper->dump(), '->dump() dumps interface injectors');
}
public function testInterfaceInjectorsAndServiceFactories()
{
$interfaceInjector = new InterfaceInjector('BarClass');
$interfaceInjector->addMethodCall('setFoo', array('someValue'));
$container = include self::$fixturesPath.'/containers/interfaces2.php';
$container->addInterfaceInjector($interfaceInjector);
$dumper = new PhpDumper($container);
$this->assertStringEqualsFile(self::$fixturesPath.'/php/services_interfaces-2.php', $dumper->dump(), '->dump() dumps interface injectors');
}
public function testFrozenContainerInterfaceInjectors()
{
$interfaceInjector = new InterfaceInjector('FooClass');
$interfaceInjector->addMethodCall('setBar', array('someValue'));
$container = include self::$fixturesPath.'/containers/interfaces1.php';
$container->addInterfaceInjector($interfaceInjector);
$container->compile();
$dumper = new PhpDumper($container);
$this->assertStringEqualsFile(self::$fixturesPath.'/php/services_interfaces-1-1.php', $dumper->dump(), '->dump() dumps interface injectors');
}
}

View File

@ -13,7 +13,6 @@ namespace Symfony\Tests\Component\DependencyInjection\Dumper;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Dumper\XmlDumper;
use Symfony\Component\DependencyInjection\InterfaceInjector;
class XmlDumperTest extends \PHPUnit_Framework_TestCase
{
@ -65,42 +64,6 @@ class XmlDumperTest extends \PHPUnit_Framework_TestCase
}
}
public function testInterfaceInjectors()
{
$interfaceInjector = new InterfaceInjector('FooClass');
$interfaceInjector->addMethodCall('setBar', array('someValue'));
$container = include self::$fixturesPath.'/containers/interfaces1.php';
$container->addInterfaceInjector($interfaceInjector);
$dumper = new XmlDumper($container);
$classBody = $dumper->dump();
//TODO: find a better way to test dumper
//var_dump($classBody);
$this->assertEquals("<?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\">
<parameters>
<parameter key=\"cla\">Fo</parameter>
<parameter key=\"ss\">Class</parameter>
</parameters>
<services>
<service id=\"foo\" class=\"%cla%o%ss%\"/>
</services>
<interfaces>
<interface class=\"FooClass\">
<call method=\"setBar\">
<argument>someValue</argument>
</call>
</interface>
</interfaces>
</container>
", $classBody);
$dom = new \DOMDocument();
$dom->loadXML($classBody);
$this->assertTrue($dom->schemaValidate(__DIR__ . '/../../../../../../src/Symfony/Component/DependencyInjection/Loader/schema/dic/services/services-1.0.xsd'));
}
public function testDumpAnonymousServices()
{
include self::$fixturesPath.'/containers/container11.php';

View File

@ -13,7 +13,6 @@ namespace Symfony\Tests\Component\DependencyInjection\Dumper;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Dumper\YamlDumper;
use Symfony\Component\DependencyInjection\InterfaceInjector;
class YamlDumperTest extends \PHPUnit_Framework_TestCase
{
@ -57,33 +56,4 @@ class YamlDumperTest extends \PHPUnit_Framework_TestCase
$this->assertEquals('Unable to dump a service container if a parameter is an object or a resource.', $e->getMessage(), '->dump() throws a RuntimeException if the container to be dumped has reference to objects or resources');
}
}
public function testInterfaceInjectors()
{
$interfaceInjector = new InterfaceInjector('FooClass');
$interfaceInjector->addMethodCall('setBar', array('someValue'));
$container = include self::$fixturesPath.'/containers/interfaces1.php';
$container->addInterfaceInjector($interfaceInjector);
$dumper = new YamlDumper($container);
$classBody = $dumper->dump();
//TODO: find a better way to test dumper
//var_dump($classBody);
$this->assertEquals("parameters:
cla: Fo
ss: Class
interfaces:
FooClass:
calls:
- [setBar, [someValue]]
services:
foo:
class: %cla%o%ss%
", $classBody);
}
}

View File

@ -1,93 +0,0 @@
<?php
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\Exception\InactiveScopeException;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\Parameter;
/**
* ProjectServiceContainer
*
* This class has been auto-generated
* by the Symfony Dependency Injection Component.
*/
class ProjectServiceContainer extends Container
{
/**
* Constructor.
*/
public function __construct()
{
$this->parameters = $this->getDefaultParameters();
$this->services =
$this->scopedServices =
$this->scopeStacks = array();
$this->set('service_container', $this);
$this->scopes = array();
$this->scopeChildren = array();
}
/**
* Gets the 'foo' service.
*
* This service is shared.
* This method always returns the same instance of the service.
*
* @return FooClass A FooClass instance.
*/
protected function getFooService()
{
$this->services['foo'] = $instance = new \FooClass();
$instance->setBar('someValue');
return $instance;
}
/**
* {@inheritdoc}
*/
public function getParameter($name)
{
$name = strtolower($name);
if (!array_key_exists($name, $this->parameters)) {
throw new \InvalidArgumentException(sprintf('The parameter "%s" must be defined.', $name));
}
return $this->parameters[$name];
}
/**
* {@inheritdoc}
*/
public function hasParameter($name)
{
return array_key_exists(strtolower($name), $this->parameters);
}
/**
* {@inheritdoc}
*/
public function setParameter($name, $value)
{
throw new \LogicException('Impossible to call set() on a frozen ParameterBag.');
}
/**
* Gets the default parameters.
*
* @return array An array of the default parameters
*/
protected function getDefaultParameters()
{
return array(
'cla' => 'Fo',
'ss' => 'Class',
);
}
}

View File

@ -1,69 +0,0 @@
<?php
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\Exception\InactiveScopeException;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\Parameter;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
/**
* ProjectServiceContainer
*
* This class has been auto-generated
* by the Symfony Dependency Injection Component.
*/
class ProjectServiceContainer extends Container
{
/**
* Constructor.
*/
public function __construct()
{
parent::__construct(new ParameterBag($this->getDefaultParameters()));
}
/**
* Gets the 'foo' service.
*
* This service is shared.
* This method always returns the same instance of the service.
*
* @return Object A %cla%o%ss% instance.
*/
protected function getFooService()
{
$class = $this->getParameter('cla').'o'.$this->getParameter('ss');
$this->services['foo'] = $instance = new $class();
$this->applyInterfaceInjectors($instance);
return $instance;
}
/**
* Gets the default parameters.
*
* @return array An array of the default parameters
*/
protected function getDefaultParameters()
{
return array(
'cla' => 'Fo',
'ss' => 'Class',
);
}
/**
* Applies all known interface injection calls
*
* @param Object $instance
*/
protected function applyInterfaceInjectors($instance)
{
if ($instance instanceof \FooClass) {
$instance->setBar('someValue');
}
}
}

View File

@ -1,73 +0,0 @@
<?php
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\Exception\InactiveScopeException;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\Parameter;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
/**
* ProjectServiceContainer
*
* This class has been auto-generated
* by the Symfony Dependency Injection Component.
*/
class ProjectServiceContainer extends Container
{
/**
* Constructor.
*/
public function __construct()
{
parent::__construct(new ParameterBag($this->getDefaultParameters()));
}
/**
* Gets the 'bar' service.
*
* This service is shared.
* This method always returns the same instance of the service.
*
* @return Object An instance returned by barFactory::createBarClass().
*/
protected function getBarService()
{
$this->services['bar'] = $instance = $this->get('barFactory')->createBarClass();
$this->applyInterfaceInjectors($instance);
return $instance;
}
/**
* Gets the 'barfactory' service.
*
* This service is shared.
* This method always returns the same instance of the service.
*
* @return BarClassFactory A BarClassFactory instance.
*/
protected function getBarfactoryService()
{
$this->services['barfactory'] = $instance = new \BarClassFactory();
$this->applyInterfaceInjectors($instance);
return $instance;
}
/**
* Applies all known interface injection calls
*
* @param Object $instance
*/
protected function applyInterfaceInjectors($instance)
{
if ($instance instanceof \BarClass) {
$instance->setFoo('someValue');
}
}
}

View File

@ -1,17 +0,0 @@
<?xml version="1.0" ?>
<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="FooClass" />
</services>
<interfaces>
<interface class="FooClass">
<call method="setBar">
<argument>correct</argument>
</call>
</interface>
</interfaces>
</container>

View File

@ -1,6 +0,0 @@
services:
foo: { class: FooClass }
interfaces:
FooClass:
calls:
- [ setBar, [ correct ] ]

View File

@ -1,178 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Tests\Component\DependencyInjection;
use Symfony\Component\DependencyInjection\InterfaceInjector;
use Symfony\Component\DependencyInjection\Definition;
class InterfaceInjectorTest extends \PHPUnit_Framework_TestCase
{
/**
* @covers Symfony\Component\DependencyInjection\InterfaceInjector::addMethodCall
* @covers Symfony\Component\DependencyInjection\InterfaceInjector::hasMethodCall
* @covers Symfony\Component\DependencyInjection\InterfaceInjector::removeMethodCall
* @covers Symfony\Component\DependencyInjection\InterfaceInjector::getMethodCalls
*
* @dataProvider getMethodCalls
*
* @param string $method
* @param array $arguments
*/
public function testAddRemoveGetMethodCalls($method, array $arguments = array())
{
$injector = new InterfaceInjector('stdClass');
$injector->addMethodCall($method, $arguments);
$this->assertTrue($injector->hasMethodCall($method), '->hasMethodCall() returns true for methods that were added on InterfaceInjector');
$methodCalls = $injector->getMethodCalls();
$this->assertEquals(1, count($methodCalls), '->getMethodCalls() returns array, where each entry is a method call');
$this->assertEquals(array($method, $arguments), $methodCalls[0], '->getMethodCalls() has all methods added to InterfaceInjector instance');
$injector->removeMethodCall($method);
$this->assertFalse($injector->hasMethodCall($method), '->removeMethodClass() deletes the method call from InterfaceInjector');
}
/**
* @covers Symfony\Component\DependencyInjection\InterfaceInjector::processDefinition
*
* @dataProvider getInjectorsAndDefinitions
*
* @param InterfaceInjector $injector
* @param Definition $definition
* @param int $expectedMethodsCount
*/
public function testProcessDefinition(InterfaceInjector $injector, Definition $definition)
{
$injector->processDefinition($definition);
}
/**
* @covers Symfony\Component\DependencyInjection\InterfaceInjector::supports
*
* @dataProvider getInjectorsAndClasses
*
* @param InterfaceInjector $injector
* @param string $class
* @param string $expectedResult
*/
public function testSupports(InterfaceInjector $injector, $class, $expectedResult)
{
$this->assertEquals($expectedResult, $injector->supports($class), '->supports() must return true if injector is to be used on a class, false otherwise');
}
/**
* @covers Symfony\Component\DependencyInjection\InterfaceInjector::processDefinition
*/
public function testProcessesDefinitionOnlyOnce()
{
$injector = new InterfaceInjector('Symfony\Tests\Component\DependencyInjection\Service');
$injector->addMethodCall('method');
$definition = $this->getMockDefinition('Symfony\Tests\Component\DependencyInjection\Service', 1);
$injector->processDefinition($definition);
$injector->processDefinition($definition);
}
/**
* @covers Symfony\Component\DependencyInjection\InterfaceInjector::merge
*/
public function testMerge()
{
$injector1 = new InterfaceInjector('Symfony\Tests\Component\DependencyInjection\Service');
$injector1->addMethodCall('method_one');
$injector2 = new InterfaceInjector('Symfony\Tests\Component\DependencyInjection\Service');
$injector2->addMethodCall('method_two');
$injector1->merge($injector2);
$methodCalls = $injector1->getMethodCalls();
$this->assertEquals(2, count($methodCalls));
$this->assertEquals(array(
array('method_one', array()),
array('method_two', array()),
), $methodCalls);
}
/**
* @expectedException Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
*/
public function testSupportsThrowsExceptionOnInvalidArgument()
{
$injector = new InterfaceInjector('Symfony\Tests\Component\DependencyInjection\Service');
$injector->supports(array());
}
public function getMethodCalls()
{
return array(
array('method', array()),
array('method2', array('one', 'two')),
array('method3', array('single')),
);
}
public function getInjectorsAndDefinitions()
{
$injector = new InterfaceInjector('Symfony\Tests\Component\DependencyInjection\Service');
$injector->addMethodCall('method');
$injector->addMethodCall('method');
$injector->addMethodCall('method');
$injector->addMethodCall('method');
$definition1 = $this->getMockDefinition('stdClass', 0);
$definition2 = $this->getMockDefinition('Symfony\Tests\Component\DependencyInjection\Service', 4);
return array(
array($injector, $definition1),
array($injector, $definition2),
);
}
public function getInjectorsAndClasses()
{
return array(
array(new InterfaceInjector('Symfony\Tests\Component\DependencyInjection\Service'), 'Symfony\Tests\Component\DependencyInjection\Service', true),
array(new InterfaceInjector('Symfony\Tests\Component\DependencyInjection\SubService'), 'Symfony\Tests\Component\DependencyInjection\Service', false),
array(new InterfaceInjector('Symfony\Tests\Component\DependencyInjection\Service'), 'Symfony\Tests\Component\DependencyInjection\SubService', true),
array(new InterfaceInjector('Symfony\Tests\Component\DependencyInjection\SubService'), 'Symfony\Tests\Component\DependencyInjection\SubService', true),
array(new InterfaceInjector('Symfony\Tests\Component\DependencyInjection\FooInterface'), 'Symfony\Tests\Component\DependencyInjection\SubService', true),
array(new InterfaceInjector('Symfony\Tests\Component\DependencyInjection\FooInterface'), 'Symfony\Tests\Component\DependencyInjection\Service', false),
array(new InterfaceInjector('Symfony\Tests\Component\DependencyInjection\FooInterface'), 'Symfony\Tests\Component\DependencyInjection\ServiceWithConstructor', false),
);
}
/**
* @param string $class
* @param int $methodCount
* @return Symfony\Component\DependencyInjection\Definition
*/
private function getMockDefinition($class, $methodCount)
{
$definition = $this->getMock('Symfony\Component\DependencyInjection\Definition');
$definition->expects($this->once())
->method('getClass')
->will($this->returnValue($class))
;
$definition->expects($this->exactly($methodCount))
->method('addMethodCall')
;
return $definition;
}
}
class ServiceWithConstructor { public function __construct(\DateTime $required) {} }
class Service {}
class SubService extends Service implements FooInterface {}
interface FooInterface {}

View File

@ -288,15 +288,4 @@ class XmlFileLoaderTest extends \PHPUnit_Framework_TestCase
$this->assertTrue($loader->supports('foo.xml'), '->supports() returns true if the resource is loadable');
$this->assertFalse($loader->supports('foo.foo'), '->supports() returns true if the resource is loadable');
}
public function testLoadInterfaceInjectors()
{
$container = new ContainerBuilder();
$loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
$loader->load('interfaces1.xml');
$interfaces = $container->getInterfaceInjectors('FooClass');
$this->assertEquals(1, count($interfaces), '->load() parses <interface> elements');
$interface = $interfaces['FooClass'];
$this->assertTrue($interface->hasMethodCall('setBar'), '->load() applies method calls correctly');
}
}

View File

@ -162,17 +162,6 @@ class YamlFileLoaderTest extends \PHPUnit_Framework_TestCase
$this->assertFalse($loader->supports('foo.foo'), '->supports() returns true if the resource is loadable');
}
public function testLoadInterfaceInjectors()
{
$container = new ContainerBuilder();
$loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml'));
$loader->load('interfaces1.yml');
$interfaces = $container->getInterfaceInjectors('FooClass');
$this->assertEquals(1, count($interfaces), '->load() parses interfaces');
$interface = $interfaces['FooClass'];
$this->assertTrue($interface->hasMethodCall('setBar'), '->load() parses interfaces elements');
}
public function testNonArrayTagThrowsException()
{
$loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/yaml'));