feature #23834 [DI] Add "PHP fluent format" for configuring the container (nicolas-grekas)
This PR was merged into the 3.4 branch.
Discussion
----------
[DI] Add "PHP fluent format" for configuring the container
| Q | A
| ------------- | ---
| Branch? | 3.4
| Bug fix? | no
| New feature? | yes
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | #22407
| License | MIT
| Doc PR | -
This PR allows one to write DI configuration using just PHP, with full IDE auto-completion.
Example:
```php
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
use Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Foo;
return function (ContainerConfigurator $c) {
$c->import('basic.php');
$s = $c->services()->defaults()
->public()
->private()
->autoconfigure()
->autowire()
->tag('t', array('a' => 'b'))
->bind(Foo::class, ref('bar'))
->private();
$s->set(Foo::class)->args([ref('bar')])->public();
$s->set('bar', Foo::class)->call('setFoo')->autoconfigure(false);
};
```
Commits
-------
814cc31
[DI] Add "PHP fluent format" for configuring the container
This commit is contained in:
commit
2f86474267
@ -0,0 +1,102 @@
|
||||
<?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\Loader\Configurator;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Argument\ArgumentInterface;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\DependencyInjection\Parameter;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
use Symfony\Component\ExpressionLanguage\Expression;
|
||||
|
||||
abstract class AbstractConfigurator
|
||||
{
|
||||
const FACTORY = 'unknown';
|
||||
|
||||
public function __call($method, $args)
|
||||
{
|
||||
if (method_exists($this, 'set'.$method)) {
|
||||
return call_user_func_array(array($this, 'set'.$method), $args);
|
||||
}
|
||||
|
||||
throw new \BadMethodCallException(sprintf('Call to undefined method %s::%s()', get_class($this), $method));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that a value is valid, optionally replacing Definition and Reference configurators by their configure value.
|
||||
*
|
||||
* @param mixed $value
|
||||
* @param bool $allowServices whether Definition and Reference are allowed; by default, only scalars and arrays are
|
||||
*
|
||||
* @return mixed the value, optionaly cast to a Definition/Reference
|
||||
*/
|
||||
public static function processValue($value, $allowServices = false)
|
||||
{
|
||||
if (is_array($value)) {
|
||||
foreach ($value as $k => $v) {
|
||||
$value[$k] = static::processValue($v, $allowServices);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
if ($value instanceof ReferenceConfigurator) {
|
||||
static $refCast;
|
||||
|
||||
if (!$refCast) {
|
||||
$refCast = \Closure::bind(function ($value) {
|
||||
return new Reference($value->id, $value->invalidBehavior);
|
||||
}, null, $value);
|
||||
}
|
||||
|
||||
// cast ReferenceConfigurator to Reference
|
||||
return $refCast($value);
|
||||
}
|
||||
|
||||
if ($value instanceof InlineServiceConfigurator) {
|
||||
static $defCast;
|
||||
|
||||
if (!$defCast) {
|
||||
$defCast = \Closure::bind(function ($value) {
|
||||
$def = $value->definition;
|
||||
$value->definition = null;
|
||||
|
||||
return $def;
|
||||
}, null, $value);
|
||||
}
|
||||
|
||||
// cast InlineServiceConfigurator to Definition
|
||||
return $defCast($value);
|
||||
}
|
||||
|
||||
if ($value instanceof self) {
|
||||
throw new InvalidArgumentException(sprintf('"%s()" can be used only at the root of service configuration files.', $value::FACTORY));
|
||||
}
|
||||
|
||||
switch (true) {
|
||||
case null === $value:
|
||||
case is_scalar($value):
|
||||
return $value;
|
||||
|
||||
case $value instanceof ArgumentInterface:
|
||||
case $value instanceof Definition:
|
||||
case $value instanceof Expression:
|
||||
case $value instanceof Parameter:
|
||||
case $value instanceof Reference:
|
||||
if ($allowServices) {
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
|
||||
throw new InvalidArgumentException(sprintf('Cannot use values of type "%s" in service configuration files.', is_object($value) ? get_class($value) : gettype($value)));
|
||||
}
|
||||
}
|
@ -0,0 +1,118 @@
|
||||
<?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\Loader\Configurator;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
|
||||
|
||||
abstract class AbstractServiceConfigurator extends AbstractConfigurator
|
||||
{
|
||||
protected $parent;
|
||||
protected $definition;
|
||||
protected $id;
|
||||
protected $defaultTags = array();
|
||||
|
||||
public function __construct(ServicesConfigurator $parent, Definition $definition, $id = null, array $defaultTags = array())
|
||||
{
|
||||
$this->parent = $parent;
|
||||
$this->definition = $definition;
|
||||
$this->id = $id;
|
||||
$this->defaultTags = $defaultTags;
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
// default tags should be added last
|
||||
foreach ($this->defaultTags as $name => $attributes) {
|
||||
foreach ($attributes as $attributes) {
|
||||
$this->definition->addTag($name, $attributes);
|
||||
}
|
||||
}
|
||||
$this->defaultTags = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a service.
|
||||
*
|
||||
* @param string $id
|
||||
* @param string|null $class
|
||||
*
|
||||
* @return ServiceConfigurator
|
||||
*/
|
||||
final public function set($id, $class = null)
|
||||
{
|
||||
$this->__destruct();
|
||||
|
||||
return $this->parent->set($id, $class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an alias.
|
||||
*
|
||||
* @param string $id
|
||||
* @param string $ref
|
||||
*
|
||||
* @return AliasConfigurator
|
||||
*/
|
||||
final public function alias($id, $referencedId)
|
||||
{
|
||||
$this->__destruct();
|
||||
|
||||
return $this->parent->alias($id, $referencedId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a PSR-4 namespace using a glob pattern.
|
||||
*
|
||||
* @param string $namespace
|
||||
* @param string $resource
|
||||
*
|
||||
* @return PrototypeConfigurator
|
||||
*/
|
||||
final public function load($namespace, $resource)
|
||||
{
|
||||
$this->__destruct();
|
||||
|
||||
return $this->parent->load($namespace, $resource);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an already defined service definition.
|
||||
*
|
||||
* @param string $id
|
||||
*
|
||||
* @return ServiceConfigurator
|
||||
*
|
||||
* @throws ServiceNotFoundException if the service definition does not exist
|
||||
*/
|
||||
final public function get($id)
|
||||
{
|
||||
$this->__destruct();
|
||||
|
||||
return $this->parent->get($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a service.
|
||||
*
|
||||
* @param string $id
|
||||
* @param string|null $class
|
||||
*
|
||||
* @return ServiceConfigurator
|
||||
*/
|
||||
final public function __invoke($id, $class = null)
|
||||
{
|
||||
$this->__destruct();
|
||||
|
||||
return $this->parent->set($id, $class);
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
<?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\Loader\Configurator;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Alias;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class AliasConfigurator extends AbstractServiceConfigurator
|
||||
{
|
||||
const FACTORY = 'alias';
|
||||
|
||||
use Traits\PublicTrait;
|
||||
|
||||
public function __construct(ServicesConfigurator $parent, Alias $alias)
|
||||
{
|
||||
$this->parent = $parent;
|
||||
$this->definition = $alias;
|
||||
}
|
||||
}
|
@ -0,0 +1,128 @@
|
||||
<?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\Loader\Configurator;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
|
||||
use Symfony\Component\ExpressionLanguage\Expression;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class ContainerConfigurator extends AbstractConfigurator
|
||||
{
|
||||
const FACTORY = 'container';
|
||||
|
||||
private $container;
|
||||
private $loader;
|
||||
private $instanceof;
|
||||
private $path;
|
||||
private $file;
|
||||
|
||||
public function __construct(ContainerBuilder $container, PhpFileLoader $loader, &$instanceof, $path, $file)
|
||||
{
|
||||
$this->container = $container;
|
||||
$this->loader = $loader;
|
||||
$this->instanceof = &$instanceof;
|
||||
$this->path = $path;
|
||||
$this->file = $file;
|
||||
}
|
||||
|
||||
final public function extension($namespace, array $config)
|
||||
{
|
||||
if (!$this->container->hasExtension($namespace)) {
|
||||
$extensions = array_filter(array_map(function ($ext) { return $ext->getAlias(); }, $this->container->getExtensions()));
|
||||
throw new InvalidArgumentException(sprintf(
|
||||
'There is no extension able to load the configuration for "%s" (in %s). Looked for namespace "%s", found %s',
|
||||
$namespace,
|
||||
$this->file,
|
||||
$namespace,
|
||||
$extensions ? sprintf('"%s"', implode('", "', $extensions)) : 'none'
|
||||
));
|
||||
}
|
||||
|
||||
$this->container->loadFromExtension($namespace, static::processValue($config));
|
||||
}
|
||||
|
||||
final public function import($resource, $type = null, $ignoreErrors = false)
|
||||
{
|
||||
$this->loader->setCurrentDir(dirname($this->path));
|
||||
$this->loader->import($resource, $type, $ignoreErrors, $this->file);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ParametersConfigurator
|
||||
*/
|
||||
public function parameters()
|
||||
{
|
||||
return new ParametersConfigurator($this->container);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ServicesConfigurator
|
||||
*/
|
||||
public function services()
|
||||
{
|
||||
return new ServicesConfigurator($this->container, $this->loader, $this->instanceof);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a service reference.
|
||||
*
|
||||
* @param string $id
|
||||
*
|
||||
* @return ReferenceConfigurator
|
||||
*/
|
||||
function ref($id)
|
||||
{
|
||||
return new ReferenceConfigurator($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an inline service.
|
||||
*
|
||||
* @param string|null $class
|
||||
*
|
||||
* @return InlineServiceConfigurator
|
||||
*/
|
||||
function inline($class = null)
|
||||
{
|
||||
return new InlineServiceConfigurator(new Definition($class));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a lazy iterator.
|
||||
*
|
||||
* @param ReferenceConfigurator[] $values
|
||||
*
|
||||
* @return IteratorArgument
|
||||
*/
|
||||
function iterator(array $values)
|
||||
{
|
||||
return new IteratorArgument(AbstractConfigurator::processValue($values, true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an expression.
|
||||
*
|
||||
* @param string $expression an expression
|
||||
*
|
||||
* @return Expression
|
||||
*/
|
||||
function expr($expression)
|
||||
{
|
||||
return new Expression($expression);
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
<?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\Loader\Configurator;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*
|
||||
* @method InstanceofConfigurator instanceof(string $fqcn)
|
||||
*/
|
||||
class DefaultsConfigurator extends AbstractServiceConfigurator
|
||||
{
|
||||
const FACTORY = 'defaults';
|
||||
|
||||
use Traits\AutoconfigureTrait;
|
||||
use Traits\AutowireTrait;
|
||||
use Traits\BindTrait;
|
||||
use Traits\PublicTrait;
|
||||
|
||||
/**
|
||||
* Adds a tag for this definition.
|
||||
*
|
||||
* @param string $name The tag name
|
||||
* @param array $attributes An array of attributes
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @throws InvalidArgumentException when an invalid tag name or attribute is provided
|
||||
*/
|
||||
final public function tag($name, array $attributes = array())
|
||||
{
|
||||
if (!is_string($name) || '' === $name) {
|
||||
throw new InvalidArgumentException(sprintf('The tag name in "_defaults" must be a non-empty string.'));
|
||||
}
|
||||
|
||||
foreach ($attributes as $attribute => $value) {
|
||||
if (!is_scalar($value) && null !== $value) {
|
||||
throw new InvalidArgumentException(sprintf('Tag "%s", attribute "%s" in "_defaults" must be of a scalar-type.', $name, $attribute));
|
||||
}
|
||||
}
|
||||
|
||||
$this->definition->addTag($name, $attributes);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines an instanceof-conditional to be applied to following service definitions.
|
||||
*
|
||||
* @param string $fqcn
|
||||
*
|
||||
* @return InstanceofConfigurator
|
||||
*/
|
||||
final protected function setInstanceof($fqcn)
|
||||
{
|
||||
return $this->parent->instanceof($fqcn);
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
<?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\Loader\Configurator;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class InlineServiceConfigurator extends AbstractConfigurator
|
||||
{
|
||||
const FACTORY = 'inline';
|
||||
|
||||
use Traits\ArgumentTrait;
|
||||
use Traits\AutowireTrait;
|
||||
use Traits\BindTrait;
|
||||
use Traits\FactoryTrait;
|
||||
use Traits\FileTrait;
|
||||
use Traits\LazyTrait;
|
||||
use Traits\ParentTrait;
|
||||
use Traits\TagTrait;
|
||||
|
||||
public function __construct(Definition $definition)
|
||||
{
|
||||
$this->definition = $definition;
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
<?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\Loader\Configurator;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*
|
||||
* @method InstanceofConfigurator instanceof(string $fqcn)
|
||||
*/
|
||||
class InstanceofConfigurator extends AbstractServiceConfigurator
|
||||
{
|
||||
const FACTORY = 'instanceof';
|
||||
|
||||
use Traits\AutowireTrait;
|
||||
use Traits\CallTrait;
|
||||
use Traits\ConfiguratorTrait;
|
||||
use Traits\LazyTrait;
|
||||
use Traits\PropertyTrait;
|
||||
use Traits\PublicTrait;
|
||||
use Traits\ShareTrait;
|
||||
use Traits\TagTrait;
|
||||
|
||||
/**
|
||||
* Defines an instanceof-conditional to be applied to following service definitions.
|
||||
*
|
||||
* @param string $fqcn
|
||||
*
|
||||
* @return InstanceofConfigurator
|
||||
*/
|
||||
final protected function setInstanceof($fqcn)
|
||||
{
|
||||
return $this->parent->instanceof($fqcn);
|
||||
}
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
<?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\Loader\Configurator;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class ParametersConfigurator extends AbstractConfigurator
|
||||
{
|
||||
const FACTORY = 'parameters';
|
||||
|
||||
private $container;
|
||||
|
||||
public function __construct(ContainerBuilder $container)
|
||||
{
|
||||
$this->container = $container;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a parameter.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $value
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
final public function set($name, $value)
|
||||
{
|
||||
$this->container->setParameter($name, static::processValue($value, true));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a parameter.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $value
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
final public function __invoke($name, $value)
|
||||
{
|
||||
return $this->set($name, $value);
|
||||
}
|
||||
}
|
@ -0,0 +1,84 @@
|
||||
<?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\Loader\Configurator;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class PrototypeConfigurator extends AbstractServiceConfigurator
|
||||
{
|
||||
const FACTORY = 'load';
|
||||
|
||||
use Traits\AbstractTrait;
|
||||
use Traits\ArgumentTrait;
|
||||
use Traits\AutoconfigureTrait;
|
||||
use Traits\AutowireTrait;
|
||||
use Traits\BindTrait;
|
||||
use Traits\CallTrait;
|
||||
use Traits\ConfiguratorTrait;
|
||||
use Traits\DeprecateTrait;
|
||||
use Traits\FactoryTrait;
|
||||
use Traits\LazyTrait;
|
||||
use Traits\ParentTrait;
|
||||
use Traits\PropertyTrait;
|
||||
use Traits\PublicTrait;
|
||||
use Traits\ShareTrait;
|
||||
use Traits\TagTrait;
|
||||
|
||||
private $loader;
|
||||
private $resource;
|
||||
private $exclude;
|
||||
private $allowParent;
|
||||
|
||||
public function __construct(ServicesConfigurator $parent, PhpFileLoader $loader, Definition $defaults, $namespace, $resource, $allowParent)
|
||||
{
|
||||
$definition = new Definition();
|
||||
$definition->setPublic($defaults->isPublic());
|
||||
$definition->setAutowired($defaults->isAutowired());
|
||||
$definition->setAutoconfigured($defaults->isAutoconfigured());
|
||||
$definition->setBindings($defaults->getBindings());
|
||||
$definition->setChanges(array());
|
||||
|
||||
$this->loader = $loader;
|
||||
$this->resource = $resource;
|
||||
$this->allowParent = $allowParent;
|
||||
|
||||
parent::__construct($parent, $definition, $namespace, $defaults->getTags());
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
parent::__destruct();
|
||||
|
||||
if ($this->loader) {
|
||||
$this->loader->registerClasses($this->definition, $this->id, $this->resource, $this->exclude);
|
||||
}
|
||||
$this->loader = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Excludes files from registration using a glob pattern.
|
||||
*
|
||||
* @param string $exclude
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
final public function exclude($exclude)
|
||||
{
|
||||
$this->exclude = $exclude;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
<?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\Loader\Configurator;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class ReferenceConfigurator
|
||||
{
|
||||
private $id;
|
||||
private $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE;
|
||||
|
||||
public function __construct($id)
|
||||
{
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
final public function ignoreOnInvalid()
|
||||
{
|
||||
$this->invalidBehavior = ContainerInterface::IGNORE_ON_INVALID_REFERENCE;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
final public function nullOnInvalid()
|
||||
{
|
||||
$this->invalidBehavior = ContainerInterface::NULL_ON_INVALID_REFERENCE;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
final public function ignoreOnUninitialized()
|
||||
{
|
||||
$this->invalidBehavior = ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
<?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\Loader\Configurator;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ChildDefinition;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class ServiceConfigurator extends AbstractServiceConfigurator
|
||||
{
|
||||
const FACTORY = 'services';
|
||||
|
||||
use Traits\AbstractTrait;
|
||||
use Traits\ArgumentTrait;
|
||||
use Traits\AutoconfigureTrait;
|
||||
use Traits\AutowireTrait;
|
||||
use Traits\BindTrait;
|
||||
use Traits\CallTrait;
|
||||
use Traits\ClassTrait;
|
||||
use Traits\ConfiguratorTrait;
|
||||
use Traits\DecorateTrait;
|
||||
use Traits\DeprecateTrait;
|
||||
use Traits\FactoryTrait;
|
||||
use Traits\FileTrait;
|
||||
use Traits\LazyTrait;
|
||||
use Traits\ParentTrait;
|
||||
use Traits\PropertyTrait;
|
||||
use Traits\PublicTrait;
|
||||
use Traits\ShareTrait;
|
||||
use Traits\SyntheticTrait;
|
||||
use Traits\TagTrait;
|
||||
|
||||
private $container;
|
||||
private $instanceof;
|
||||
private $allowParent;
|
||||
|
||||
public function __construct(ContainerBuilder $container, array $instanceof, $allowParent, ServicesConfigurator $parent, Definition $definition, $id, array $defaultTags)
|
||||
{
|
||||
$this->container = $container;
|
||||
$this->instanceof = $instanceof;
|
||||
$this->allowParent = $allowParent;
|
||||
|
||||
parent::__construct($parent, $definition, $id, $defaultTags);
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
parent::__destruct();
|
||||
|
||||
if (!$this->definition instanceof ChildDefinition) {
|
||||
$this->container->setDefinition($this->id, $this->definition->setInstanceofConditionals($this->instanceof));
|
||||
} else {
|
||||
$this->container->setDefinition($this->id, $this->definition);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,154 @@
|
||||
<?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\Loader\Configurator;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Alias;
|
||||
use Symfony\Component\DependencyInjection\ChildDefinition;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
|
||||
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*
|
||||
* @method InstanceofConfigurator instanceof($fqcn)
|
||||
*/
|
||||
class ServicesConfigurator extends AbstractConfigurator
|
||||
{
|
||||
const FACTORY = 'services';
|
||||
|
||||
private $defaults;
|
||||
private $container;
|
||||
private $loader;
|
||||
private $instanceof;
|
||||
|
||||
public function __construct(ContainerBuilder $container, PhpFileLoader $loader, array &$instanceof)
|
||||
{
|
||||
$this->defaults = new Definition();
|
||||
$this->container = $container;
|
||||
$this->loader = $loader;
|
||||
$this->instanceof = &$instanceof;
|
||||
$instanceof = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines a set of defaults for following service definitions.
|
||||
*
|
||||
* @return DefaultsConfigurator
|
||||
*/
|
||||
public function defaults()
|
||||
{
|
||||
return new DefaultsConfigurator($this, $this->defaults = new Definition());
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines an instanceof-conditional to be applied to following service definitions.
|
||||
*
|
||||
* @param string $fqcn
|
||||
*
|
||||
* @return InstanceofConfigurator
|
||||
*/
|
||||
final protected function setInstanceof($fqcn)
|
||||
{
|
||||
$this->instanceof[$fqcn] = $definition = new ChildDefinition('');
|
||||
|
||||
return new InstanceofConfigurator($this, $definition, $fqcn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a service.
|
||||
*
|
||||
* @param string $id
|
||||
* @param string|null $class
|
||||
*
|
||||
* @return ServiceConfigurator
|
||||
*/
|
||||
final public function set($id, $class = null)
|
||||
{
|
||||
$defaults = $this->defaults;
|
||||
$allowParent = !$defaults->getChanges() && empty($this->instanceof);
|
||||
|
||||
$definition = new Definition();
|
||||
$definition->setPublic($defaults->isPublic());
|
||||
$definition->setAutowired($defaults->isAutowired());
|
||||
$definition->setAutoconfigured($defaults->isAutoconfigured());
|
||||
$definition->setBindings($defaults->getBindings());
|
||||
$definition->setChanges(array());
|
||||
|
||||
$configurator = new ServiceConfigurator($this->container, $this->instanceof, $allowParent, $this, $definition, $id, $defaults->getTags());
|
||||
|
||||
return null !== $class ? $configurator->class($class) : $configurator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an alias.
|
||||
*
|
||||
* @param string $id
|
||||
* @param string $referencedId
|
||||
*
|
||||
* @return AliasConfigurator
|
||||
*/
|
||||
final public function alias($id, $referencedId)
|
||||
{
|
||||
$ref = static::processValue($referencedId, true);
|
||||
$alias = new Alias((string) $ref, $this->defaults->isPublic());
|
||||
$this->container->setAlias($id, $alias);
|
||||
|
||||
return new AliasConfigurator($this, $alias);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a PSR-4 namespace using a glob pattern.
|
||||
*
|
||||
* @param string $namespace
|
||||
* @param string $resource
|
||||
*
|
||||
* @return PrototypeConfigurator
|
||||
*/
|
||||
final public function load($namespace, $resource)
|
||||
{
|
||||
$allowParent = !$this->defaults->getChanges() && empty($this->instanceof);
|
||||
|
||||
return new PrototypeConfigurator($this, $this->loader, $this->defaults, $namespace, $resource, $allowParent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an already defined service definition.
|
||||
*
|
||||
* @param string $id
|
||||
*
|
||||
* @return ServiceConfigurator
|
||||
*
|
||||
* @throws ServiceNotFoundException if the service definition does not exist
|
||||
*/
|
||||
final public function get($id)
|
||||
{
|
||||
$allowParent = !$this->defaults->getChanges() && empty($this->instanceof);
|
||||
$definition = $this->container->getDefinition($id);
|
||||
|
||||
return new ServiceConfigurator($this->container, $definition->getInstanceofConditionals(), $allowParent, $this, $definition, $id, array());
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a service.
|
||||
*
|
||||
* @param string $id
|
||||
* @param string|null $class
|
||||
*
|
||||
* @return ServiceConfigurator
|
||||
*/
|
||||
final public function __invoke($id, $class = null)
|
||||
{
|
||||
return $this->set($id, $class);
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
<?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\Loader\Configurator\Traits;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
|
||||
/**
|
||||
* @method $this abstract(bool $abstract = true)
|
||||
*/
|
||||
trait AbstractTrait
|
||||
{
|
||||
/**
|
||||
* Whether this definition is abstract, that means it merely serves as a
|
||||
* template for other definitions.
|
||||
*
|
||||
* @param bool $abstract
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
final protected function setAbstract($abstract = true)
|
||||
{
|
||||
$this->definition->setAbstract($abstract);
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
<?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\Loader\Configurator\Traits;
|
||||
|
||||
trait ArgumentTrait
|
||||
{
|
||||
/**
|
||||
* Sets the arguments to pass to the service constructor/factory method.
|
||||
*
|
||||
* @param array $arguments An array of arguments
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
final public function args(array $arguments)
|
||||
{
|
||||
$this->definition->setArguments(static::processValue($arguments, true));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets one argument to pass to the service constructor/factory method.
|
||||
*
|
||||
* @param string|int $key
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
final public function arg($key, $value)
|
||||
{
|
||||
$this->definition->setArgument($key, static::processValue($value, true));
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
<?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\Loader\Configurator\Traits;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
|
||||
trait AutoconfigureTrait
|
||||
{
|
||||
/**
|
||||
* Sets whether or not instanceof conditionals should be prepended with a global set.
|
||||
*
|
||||
* @param bool $autoconfigured
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @throws InvalidArgumentException when a parent is already set
|
||||
*/
|
||||
final public function autoconfigure($autoconfigured = true)
|
||||
{
|
||||
if ($autoconfigured && $this->definition instanceof ChildDefinition) {
|
||||
throw new InvalidArgumentException(sprintf('The service "%s" cannot have a "parent" and also have "autoconfigure". Try disabling autoconfiguration for the service.', $this->id));
|
||||
}
|
||||
$this->definition->setAutoconfigured($autoconfigured);
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
<?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\Loader\Configurator\Traits;
|
||||
|
||||
trait AutowireTrait
|
||||
{
|
||||
/**
|
||||
* Enables/disables autowiring.
|
||||
*
|
||||
* @param bool $autowired
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
final public function autowire($autowired = true)
|
||||
{
|
||||
$this->definition->setAutowired($autowired);
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
<?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\Loader\Configurator\Traits;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
|
||||
trait BindTrait
|
||||
{
|
||||
/**
|
||||
* Sets bindings.
|
||||
*
|
||||
* Bindings map $named or FQCN arguments to values that should be
|
||||
* injected in the matching parameters (of the constructor, of methods
|
||||
* called and of controller actions).
|
||||
*
|
||||
* @param string $nameOrFqcn A parameter name with its "$" prefix, or a FQCN
|
||||
* @param mixed $valueOrRef The value or reference to bind
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
final public function bind($nameOrFqcn, $valueOrRef)
|
||||
{
|
||||
$valueOrRef = static::processValue($valueOrRef, true);
|
||||
if (isset($nameOrFqcn[0]) && '$' !== $nameOrFqcn[0] && !$valueOrRef instanceof Reference) {
|
||||
throw new InvalidArgumentException(sprintf('Invalid binding for service "%s": named arguments must start with a "$", and FQCN must map to references. Neither applies to binding "%s".', $this->id, $nameOrFqcn));
|
||||
}
|
||||
$bindings = $this->definition->getBindings();
|
||||
$bindings[$nameOrFqcn] = $valueOrRef;
|
||||
$this->definition->setBindings($bindings);
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
<?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\Loader\Configurator\Traits;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
|
||||
trait CallTrait
|
||||
{
|
||||
/**
|
||||
* Adds a method to call after service initialization.
|
||||
*
|
||||
* @param string $method The method name to call
|
||||
* @param array $arguments An array of arguments to pass to the method call
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @throws InvalidArgumentException on empty $method param
|
||||
*/
|
||||
final public function call($method, array $arguments = array())
|
||||
{
|
||||
$this->definition->addMethodCall($method, static::processValue($arguments, true));
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
<?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\Loader\Configurator\Traits;
|
||||
|
||||
/**
|
||||
* @method $this class(string $class)
|
||||
*/
|
||||
trait ClassTrait
|
||||
{
|
||||
/**
|
||||
* Sets the service class.
|
||||
*
|
||||
* @param string $class The service class
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
final protected function setClass($class)
|
||||
{
|
||||
$this->definition->setClass($class);
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
<?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\Loader\Configurator\Traits;
|
||||
|
||||
trait ConfiguratorTrait
|
||||
{
|
||||
/**
|
||||
* Sets a configurator to call after the service is fully initialized.
|
||||
*
|
||||
* @param string|array $configurator A PHP callable reference
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
final public function configurator($configurator)
|
||||
{
|
||||
$this->definition->setConfigurator(static::processValue($configurator, true));
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
<?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\Loader\Configurator\Traits;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
|
||||
trait DecorateTrait
|
||||
{
|
||||
/**
|
||||
* Sets the service that this service is decorating.
|
||||
*
|
||||
* @param null|string $id The decorated service id, use null to remove decoration
|
||||
* @param null|string $renamedId The new decorated service id
|
||||
* @param int $priority The priority of decoration
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @throws InvalidArgumentException in case the decorated service id and the new decorated service id are equals
|
||||
*/
|
||||
final public function decorate($id, $renamedId = null, $priority = 0)
|
||||
{
|
||||
$this->definition->setDecoratedService($id, $renamedId, $priority);
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
<?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\Loader\Configurator\Traits;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
|
||||
trait DeprecateTrait
|
||||
{
|
||||
/**
|
||||
* Whether this definition is deprecated, that means it should not be called anymore.
|
||||
*
|
||||
* @param string $template Template message to use if the definition is deprecated
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @throws InvalidArgumentException when the message template is invalid
|
||||
*/
|
||||
final public function deprecate($template = null)
|
||||
{
|
||||
$this->definition->setDeprecated(true, $template);
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
<?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\Loader\Configurator\Traits;
|
||||
|
||||
trait FactoryTrait
|
||||
{
|
||||
/**
|
||||
* Sets a factory.
|
||||
*
|
||||
* @param string|array $factory A PHP callable reference
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
final public function factory($factory)
|
||||
{
|
||||
$this->definition->setFactory(static::processValue($factory, true));
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
<?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\Loader\Configurator\Traits;
|
||||
|
||||
trait FileTrait
|
||||
{
|
||||
/**
|
||||
* Sets a file to require before creating the service.
|
||||
*
|
||||
* @param string $file A full pathname to include
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
final public function file($file)
|
||||
{
|
||||
$this->definition->setFile($file);
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
<?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\Loader\Configurator\Traits;
|
||||
|
||||
trait LazyTrait
|
||||
{
|
||||
/**
|
||||
* Sets the lazy flag of this service.
|
||||
*
|
||||
* @param bool $lazy
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
final public function lazy($lazy = true)
|
||||
{
|
||||
$this->definition->setLazy($lazy);
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
<?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\Loader\Configurator\Traits;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ChildDefinition;
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* @method $this parent(string $parent)
|
||||
*/
|
||||
trait ParentTrait
|
||||
{
|
||||
/**
|
||||
* Sets the Definition to inherit from.
|
||||
*
|
||||
* @param string $parent
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @throws InvalidArgumentException when parent cannot be set
|
||||
*/
|
||||
final protected function setParent($parent)
|
||||
{
|
||||
if (!$this->allowParent) {
|
||||
throw new InvalidArgumentException(sprintf('A parent cannot be defined when either "_instanceof" or "_defaults" are also defined for service prototype "%s".', $this->id));
|
||||
}
|
||||
|
||||
if ($this->definition instanceof ChildDefinition) {
|
||||
$this->definition->setParent($parent);
|
||||
} elseif ($this->definition->isAutoconfigured()) {
|
||||
throw new InvalidArgumentException(sprintf('The service "%s" cannot have a "parent" and also have "autoconfigure". Try disabling autoconfiguration for the service.', $this->id));
|
||||
} else {
|
||||
// cast Definition to ChildDefinition
|
||||
$definition = serialize($this->definition);
|
||||
$definition = substr_replace($definition, '53', 2, 2);
|
||||
$definition = substr_replace($definition, 'Child', 44, 0);
|
||||
$definition = unserialize($definition);
|
||||
|
||||
$this->definition = $definition->setParent($parent);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
<?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\Loader\Configurator\Traits;
|
||||
|
||||
trait PropertyTrait
|
||||
{
|
||||
/**
|
||||
* Sets a specific property.
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
final public function property($name, $value)
|
||||
{
|
||||
$this->definition->setProperty($name, static::processValue($value, true));
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
<?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\Loader\Configurator\Traits;
|
||||
|
||||
/**
|
||||
* @method $this public()
|
||||
* @method $this private()
|
||||
*/
|
||||
trait PublicTrait
|
||||
{
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
final protected function setPublic()
|
||||
{
|
||||
$this->definition->setPublic(true);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
final protected function setPrivate()
|
||||
{
|
||||
$this->definition->setPublic(false);
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
<?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\Loader\Configurator\Traits;
|
||||
|
||||
trait ShareTrait
|
||||
{
|
||||
/**
|
||||
* Sets if the service must be shared or not.
|
||||
*
|
||||
* @param bool $shared Whether the service must be shared or not
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
final public function share($shared = true)
|
||||
{
|
||||
$this->definition->setShared($shared);
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
<?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\Loader\Configurator\Traits;
|
||||
|
||||
trait SyntheticTrait
|
||||
{
|
||||
/**
|
||||
* Sets whether this definition is synthetic, that is not constructed by the
|
||||
* container, but dynamically injected.
|
||||
*
|
||||
* @param bool $synthetic
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
final public function synthetic($synthetic = true)
|
||||
{
|
||||
$this->definition->setSynthetic($synthetic);
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
<?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\Loader\Configurator\Traits;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
|
||||
trait TagTrait
|
||||
{
|
||||
/**
|
||||
* Adds a tag for this definition.
|
||||
*
|
||||
* @param string $name The tag name
|
||||
* @param array $attributes An array of attributes
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
final public function tag($name, array $attributes = array())
|
||||
{
|
||||
if (!is_string($name) || '' === $name) {
|
||||
throw new InvalidArgumentException(sprintf('The tag name for service "%s" must be a non-empty string.', $this->id));
|
||||
}
|
||||
|
||||
foreach ($attributes as $attribute => $value) {
|
||||
if (!is_scalar($value) && null !== $value) {
|
||||
throw new InvalidArgumentException(sprintf('A tag attribute must be of a scalar-type for service "%s", tag "%s", attribute "%s".', $this->id, $name, $attribute));
|
||||
}
|
||||
}
|
||||
|
||||
$this->definition->addTag($name, $attributes);
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
@ -11,6 +11,8 @@
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Loader;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
|
||||
/**
|
||||
* PhpFileLoader loads service definitions from a PHP file.
|
||||
*
|
||||
@ -34,7 +36,16 @@ class PhpFileLoader extends FileLoader
|
||||
$this->setCurrentDir(dirname($path));
|
||||
$this->container->fileExists($path);
|
||||
|
||||
include $path;
|
||||
// the closure forbids access to the private scope in the included file
|
||||
$load = \Closure::bind(function ($path) use ($container, $loader, $resource, $type) {
|
||||
return include $path;
|
||||
}, $this, ProtectedPhpFileLoader::class);
|
||||
|
||||
$callback = $load($path);
|
||||
|
||||
if ($callback instanceof \Closure) {
|
||||
$callback(new ContainerConfigurator($this->container, $this, $this->instanceof, $path, $resource), $this->container, $this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -53,3 +64,10 @@ class PhpFileLoader extends FileLoader
|
||||
return 'php' === $type;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
final class ProtectedPhpFileLoader extends PhpFileLoader
|
||||
{
|
||||
}
|
||||
|
@ -3,5 +3,12 @@
|
||||
namespace Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype;
|
||||
|
||||
class Foo
|
||||
{
|
||||
public function __construct($bar = null)
|
||||
{
|
||||
}
|
||||
|
||||
function setFoo(self $foo)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,10 @@
|
||||
|
||||
services:
|
||||
service_container:
|
||||
class: Symfony\Component\DependencyInjection\ContainerInterface
|
||||
public: true
|
||||
synthetic: true
|
||||
App\BarService:
|
||||
class: App\BarService
|
||||
public: true
|
||||
arguments: [!service { class: FooClass }]
|
@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
|
||||
|
||||
use App\BarService;
|
||||
|
||||
return function (ContainerConfigurator $c) {
|
||||
|
||||
$s = $c->services();
|
||||
$s->set(BarService::class)
|
||||
->args(array(inline('FooClass')));
|
||||
|
||||
};
|
@ -0,0 +1,15 @@
|
||||
|
||||
services:
|
||||
service_container:
|
||||
class: Symfony\Component\DependencyInjection\ContainerInterface
|
||||
public: true
|
||||
synthetic: true
|
||||
foo:
|
||||
class: Class2
|
||||
public: true
|
||||
file: file.php
|
||||
lazy: true
|
||||
arguments: [!service { class: Class1, public: false }]
|
||||
bar:
|
||||
alias: foo
|
||||
public: true
|
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
|
||||
|
||||
use App\BarService;
|
||||
|
||||
return function (ContainerConfigurator $c) {
|
||||
|
||||
$c->services()
|
||||
->set('bar', 'Class1')
|
||||
->set(BarService::class)
|
||||
->abstract(true)
|
||||
->lazy()
|
||||
->set('foo')
|
||||
->parent(BarService::class)
|
||||
->decorate('bar', 'b', 1)
|
||||
->args(array(ref('b')))
|
||||
->class('Class2')
|
||||
->file('file.php')
|
||||
->parent('bar')
|
||||
->parent(BarService::class)
|
||||
;
|
||||
|
||||
};
|
@ -0,0 +1,27 @@
|
||||
|
||||
services:
|
||||
service_container:
|
||||
class: Symfony\Component\DependencyInjection\ContainerInterface
|
||||
public: true
|
||||
synthetic: true
|
||||
App\BarService:
|
||||
class: App\BarService
|
||||
public: true
|
||||
arguments: [!service { class: FooClass }]
|
||||
Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Foo:
|
||||
class: Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Foo
|
||||
public: true
|
||||
tags:
|
||||
- { name: t, a: b }
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
arguments: ['@bar']
|
||||
bar:
|
||||
class: Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Foo
|
||||
public: false
|
||||
tags:
|
||||
- { name: t, a: b }
|
||||
autowire: true
|
||||
calls:
|
||||
- [setFoo, ['@bar']]
|
||||
|
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Foo;
|
||||
|
||||
return function (ContainerConfigurator $c) {
|
||||
|
||||
$c->import('basic.php');
|
||||
|
||||
$s = $c->services()->defaults()
|
||||
->public()
|
||||
->private()
|
||||
->autoconfigure()
|
||||
->autowire()
|
||||
->tag('t', array('a' => 'b'))
|
||||
->bind(Foo::class, ref('bar'))
|
||||
->private();
|
||||
|
||||
$s->set(Foo::class)->args(array(ref('bar')))->public();
|
||||
$s->set('bar', Foo::class)->call('setFoo')->autoconfigure(false);
|
||||
|
||||
};
|
@ -0,0 +1,21 @@
|
||||
|
||||
services:
|
||||
service_container:
|
||||
class: Symfony\Component\DependencyInjection\ContainerInterface
|
||||
public: true
|
||||
synthetic: true
|
||||
Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Foo:
|
||||
class: Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Foo
|
||||
public: true
|
||||
tags:
|
||||
- { name: tag, k: v }
|
||||
lazy: true
|
||||
properties: { p: 1 }
|
||||
calls:
|
||||
- [setFoo, ['@foo']]
|
||||
|
||||
shared: false
|
||||
configurator: c
|
||||
foo:
|
||||
class: App\FooService
|
||||
public: true
|
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
|
||||
|
||||
use App\FooService;
|
||||
use Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype;
|
||||
|
||||
return function (ContainerConfigurator $c) {
|
||||
|
||||
$s = $c->services();
|
||||
$s->instanceof(Prototype\Foo::class)
|
||||
->property('p', 0)
|
||||
->call('setFoo', array(ref('foo')))
|
||||
->tag('tag', array('k' => 'v'))
|
||||
->share(false)
|
||||
->lazy()
|
||||
->configurator('c')
|
||||
->property('p', 1);
|
||||
|
||||
$s->load(Prototype::class.'\\', '../Prototype')->exclude('../Prototype/*/*');
|
||||
|
||||
$s->set('foo', FooService::class);
|
||||
|
||||
};
|
@ -0,0 +1,19 @@
|
||||
parameters:
|
||||
foo: Foo
|
||||
bar: Bar
|
||||
|
||||
services:
|
||||
service_container:
|
||||
class: Symfony\Component\DependencyInjection\ContainerInterface
|
||||
public: true
|
||||
synthetic: true
|
||||
Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Foo:
|
||||
class: Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Foo
|
||||
public: true
|
||||
arguments: ['@bar']
|
||||
bar:
|
||||
class: Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Foo
|
||||
public: true
|
||||
calls:
|
||||
- [setFoo, { }]
|
||||
|
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Foo;
|
||||
|
||||
return function (ContainerConfigurator $c) {
|
||||
|
||||
$c->parameters()
|
||||
('foo', 'Foo')
|
||||
('bar', 'Bar')
|
||||
;
|
||||
$c->services()
|
||||
(Foo::class)
|
||||
->arg('$bar', ref('bar'))
|
||||
->public()
|
||||
('bar', Foo::class)
|
||||
->call('setFoo')
|
||||
;
|
||||
|
||||
};
|
@ -0,0 +1,25 @@
|
||||
|
||||
services:
|
||||
service_container:
|
||||
class: Symfony\Component\DependencyInjection\ContainerInterface
|
||||
public: true
|
||||
synthetic: true
|
||||
Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Foo:
|
||||
class: Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Foo
|
||||
public: true
|
||||
tags:
|
||||
- { name: foo }
|
||||
- { name: baz }
|
||||
deprecated: %service_id%
|
||||
arguments: [1]
|
||||
factory: f
|
||||
Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Sub\Bar:
|
||||
class: Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Sub\Bar
|
||||
public: true
|
||||
tags:
|
||||
- { name: foo }
|
||||
- { name: baz }
|
||||
deprecated: %service_id%
|
||||
lazy: true
|
||||
arguments: [1]
|
||||
factory: f
|
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype;
|
||||
|
||||
return function (ContainerConfigurator $c) {
|
||||
|
||||
$di = $c->services()->defaults()
|
||||
->tag('baz');
|
||||
$di->load(Prototype::class.'\\', '../Prototype')
|
||||
->autoconfigure()
|
||||
->exclude('../Prototype/{OtherDir}')
|
||||
->factory('f')
|
||||
->deprecate('%service_id%')
|
||||
->args(array(0))
|
||||
->args(array(1))
|
||||
->autoconfigure(false)
|
||||
->tag('foo')
|
||||
->parent('foo');
|
||||
$di->set('foo')->lazy()->abstract();
|
||||
$di->get(Prototype\Foo::class)->lazy(false);
|
||||
|
||||
};
|
@ -0,0 +1,122 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
|
||||
|
||||
use Bar\FooClass;
|
||||
use Symfony\Component\DependencyInjection\Parameter;
|
||||
|
||||
require_once __DIR__.'/../includes/classes.php';
|
||||
require_once __DIR__.'/../includes/foo.php';
|
||||
|
||||
return function (ContainerConfigurator $c) {
|
||||
|
||||
$p = $c->parameters();
|
||||
$p->set('baz_class', 'BazClass');
|
||||
$p->set('foo_class', FooClass::class)
|
||||
->set('foo', 'bar');
|
||||
|
||||
$s = $c->services();
|
||||
$s->set('foo')
|
||||
->args(array('foo', ref('foo.baz'), array('%foo%' => 'foo is %foo%', 'foobar' => '%foo%'), true, ref('service_container')))
|
||||
->class(FooClass::class)
|
||||
->tag('foo', array('foo' => 'foo'))
|
||||
->tag('foo', array('bar' => 'bar', 'baz' => 'baz'))
|
||||
->factory(array(FooClass::class, 'getInstance'))
|
||||
->property('foo', 'bar')
|
||||
->property('moo', ref('foo.baz'))
|
||||
->property('qux', array('%foo%' => 'foo is %foo%', 'foobar' => '%foo%'))
|
||||
->call('setBar', array(ref('bar')))
|
||||
->call('initialize')
|
||||
->configurator('sc_configure');
|
||||
|
||||
$s->set('foo.baz', '%baz_class%')
|
||||
->factory(array('%baz_class%', 'getInstance'))
|
||||
->configurator(array('%baz_class%', 'configureStatic1'));
|
||||
|
||||
$s->set('bar', FooClass::class)
|
||||
->args(array('foo', ref('foo.baz'), new Parameter('foo_bar')))
|
||||
->configurator(array(ref('foo.baz'), 'configure'));
|
||||
|
||||
$s->set('foo_bar', '%foo_class%')
|
||||
->args(array(ref('deprecated_service')))
|
||||
->share(false);
|
||||
|
||||
$s->alias('alias_for_foo', 'foo')->private()->public();
|
||||
$s->alias('alias_for_alias', ref('alias_for_foo'));
|
||||
|
||||
$s->set('method_call1', 'Bar\FooClass')
|
||||
->file(realpath(__DIR__.'/../includes/foo.php'))
|
||||
->call('setBar', array(ref('foo')))
|
||||
->call('setBar', array(ref('foo2')->nullOnInvalid()))
|
||||
->call('setBar', array(ref('foo3')->ignoreOnInvalid()))
|
||||
->call('setBar', array(ref('foobaz')->ignoreOnInvalid()))
|
||||
->call('setBar', array(expr('service("foo").foo() ~ (container.hasParameter("foo") ? parameter("foo") : "default")')));
|
||||
|
||||
$s->set('foo_with_inline', 'Foo')
|
||||
->call('setBar', array(ref('inlined')));
|
||||
|
||||
$s->set('inlined', 'Bar')
|
||||
->property('pub', 'pub')
|
||||
->call('setBaz', array(ref('baz')))
|
||||
->private();
|
||||
|
||||
$s->set('baz', 'Baz')
|
||||
->call('setFoo', array(ref('foo_with_inline')));
|
||||
|
||||
$s->set('request', 'Request')
|
||||
->synthetic();
|
||||
|
||||
$s->set('configurator_service', 'ConfClass')
|
||||
->private()
|
||||
->call('setFoo', array(ref('baz')));
|
||||
|
||||
$s->set('configured_service', 'stdClass')
|
||||
->configurator(array(ref('configurator_service'), 'configureStdClass'));
|
||||
|
||||
$s->set('configurator_service_simple', 'ConfClass')
|
||||
->args(array('bar'))
|
||||
->private();
|
||||
|
||||
$s->set('configured_service_simple', 'stdClass')
|
||||
->configurator(array(ref('configurator_service_simple'), 'configureStdClass'));
|
||||
|
||||
$s->set('decorated', 'stdClass');
|
||||
|
||||
$s->set('decorator_service', 'stdClass')
|
||||
->decorate('decorated');
|
||||
|
||||
$s->set('decorator_service_with_name', 'stdClass')
|
||||
->decorate('decorated', 'decorated.pif-pouf');
|
||||
|
||||
$s->set('deprecated_service', 'stdClass')
|
||||
->deprecate();
|
||||
|
||||
$s->set('new_factory', 'FactoryClass')
|
||||
->property('foo', 'bar')
|
||||
->private();
|
||||
|
||||
$s->set('factory_service', 'Bar')
|
||||
->factory(array(ref('foo.baz'), 'getInstance'));
|
||||
|
||||
$s->set('new_factory_service', 'FooBarBaz')
|
||||
->property('foo', 'bar')
|
||||
->factory(array(ref('new_factory'), 'getInstance'));
|
||||
|
||||
$s->set('service_from_static_method', 'Bar\FooClass')
|
||||
->factory(array('Bar\FooClass', 'getInstance'));
|
||||
|
||||
$s->set('factory_simple', 'SimpleFactoryClass')
|
||||
->deprecate()
|
||||
->args(array('foo'))
|
||||
->private();
|
||||
|
||||
$s->set('factory_service_simple', 'Bar')
|
||||
->factory(array(ref('factory_simple'), 'getInstance'));
|
||||
|
||||
$s->set('lazy_context', 'LazyContext')
|
||||
->args(array(iterator(array('k1' => ref('foo.baz'), 'k2' => ref('service_container'))), iterator(array())));
|
||||
|
||||
$s->set('lazy_context_ignore_invalid_ref', 'LazyContext')
|
||||
->args(array(iterator(array(ref('foo.baz'), ref('invalid')->ignoreOnInvalid())), iterator(array())));
|
||||
|
||||
};
|
@ -13,6 +13,8 @@ namespace Symfony\Component\DependencyInjection\Tests\Loader;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Dumper\PhpDumper;
|
||||
use Symfony\Component\DependencyInjection\Dumper\YamlDumper;
|
||||
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
|
||||
use Symfony\Component\Config\FileLocator;
|
||||
|
||||
@ -35,4 +37,43 @@ class PhpFileLoaderTest extends TestCase
|
||||
|
||||
$this->assertEquals('foo', $container->getParameter('foo'), '->load() loads a PHP file resource');
|
||||
}
|
||||
|
||||
public function testConfigServices()
|
||||
{
|
||||
$fixtures = realpath(__DIR__.'/../Fixtures');
|
||||
$loader = new PhpFileLoader($container = new ContainerBuilder(), new FileLocator());
|
||||
$loader->load($fixtures.'/config/services9.php');
|
||||
|
||||
$container->compile();
|
||||
$dumper = new PhpDumper($container);
|
||||
$this->assertStringEqualsFile($fixtures.'/php/services9_compiled.php', str_replace(str_replace('\\', '\\\\', $fixtures.DIRECTORY_SEPARATOR.'includes'.DIRECTORY_SEPARATOR), '%path%', $dumper->dump()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideConfig
|
||||
*/
|
||||
public function testConfig($file)
|
||||
{
|
||||
$fixtures = realpath(__DIR__.'/../Fixtures');
|
||||
$loader = new PhpFileLoader($container = new ContainerBuilder(), new FileLocator());
|
||||
$loader->load($fixtures.'/config/'.$file.'.php');
|
||||
|
||||
$container->compile();
|
||||
|
||||
$dumper = new YamlDumper($container);
|
||||
$this->assertStringEqualsFile($fixtures.'/config/'.$file.'.expected.yml', $dumper->dump());
|
||||
}
|
||||
|
||||
public function provideConfig()
|
||||
{
|
||||
yield array('basic');
|
||||
yield array('defaults');
|
||||
yield array('instanceof');
|
||||
yield array('prototype');
|
||||
yield array('child');
|
||||
|
||||
if (\PHP_VERSION_ID >= 70000) {
|
||||
yield array('php7');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user