8000 [DependencyInjection] Add autowiring capabilities by dunglas · Pull Request #15613 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content

[DependencyInjection] Add autowiring capabilities #15613

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 19 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8000
Prev Previous commit
Next Next commit
Flag to enable/disable autowiring. no_autowiring tag.
  • Loading branch information
dunglas committed Oct 1, 2015
commit afe009ad399442b3d1b12c40fb8da6eb1ef036bd
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
<argument type="service" id="annotations.reader" />
<argument /><!-- Cache Implementation -->
<argument /><!-- Debug-Flag -->

<tag name="no_autowiring" />
</service>

<service id="annotations.file_cache_reader" class="%annotations.file_cache_reader.class%" public="false">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,9 @@
<argument>%session.save_path%</argument>
</service>

<service id="session.handler.write_check" class="%session.handler.write_check.class%" public="false" />
<service id="session.handler.write_check" class="%session.handler.write_check.class%" public="false">
<tag name="no_autowiring" />
</service>

<service id="session_listener" class="%session_listener.class%">
<tag name="kernel.event_subscriber" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
*/
class AutowiringPass implements CompilerPassInterface
{
const NO_AUTOWIRING = 'no_autowiring';

private $container;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why storing the container? Can't you just pass it explicitly to your private methods?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As this class already has a lot of states, it's just to avoid passing the container as argument of other methods.
I can rewrite this class without states but not sure it has any interest (and other passes also have states).

private $reflectionClasses = array();
private $definedTypes = array();
Expand All @@ -36,7 +38,9 @@ public function process(ContainerBuilder $container)
{
$this->container = $container;
foreach ($container->getDefinitions() as $id => $definition) {
$this->completeDefinition($id, $definition);
if (!$definition->hasTag(self::NO_AUTOWIRING)) {
$this->completeDefinition($id, $definition);
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please reset all the internal state at the end of the method to release memory (many things are not needed at all anymore, and there is no reason to kep a circular reference between the ContainerBuilder and this pass)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why aren't you using $container->findTaggedServiceIds instead ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, I'll take a look at that.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because I need the definition instance and not the tags.


// Free memory and remove circular reference to container
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,12 @@ class Compiler

/**
* Constructor.
*
* @param bool $autowiring Enable the autowiring
*/
public function __construct()
public function __construct($autowiring = false)
{
$this->passConfig = new PassConfig();
$this->passConfig = new PassConfig($autowiring);
$this->serviceReferenceGraph = new ServiceReferenceGraph();
$this->loggingFormatter = new LoggingFormatter();
}
Expand Down
14 changes: 11 additions & 3 deletions src/Symfony/Component/DependencyInjection/Compiler/PassConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,10 @@ class PassConfig

/**
* Constructor.
*
* @param bool $autowiring Enable the autowiring
*/
public function __construct()
public function __construct($autowiring = false)
{
$this->mergePass = new MergeExtensionConfigurationPass();

Expand All @@ -50,11 +52,17 @@ public function __construct()
new CheckDefinitionValidityPass(),
new ResolveReferencesToAliasesPass(),
new ResolveInvalidReferencesPass(),
new AutowiringPass(),
);

if ($autowiring) {
$this->optimizationPasses[] = new AutowiringPass();
}

$this->optimizationPasses = array_merge($this->optimizationPasses, array(
new AnalyzeServiceReferencesPass(true),
new CheckCircularReferencesPass(),
new CheckReferenceValidityPass(),
);
));

$this->removingPasses = array(
new RemovePrivateAliasesPass(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ public function getCompilerPassConfig()
public function getCompiler()
{
if (null === $this->compiler) {
$this->compiler = new Compiler();
$this->compiler = new Compiler($this->hasParameter('container.autowiring') ? $this->getParameter('container.autowiring') : false);
}

return $this->compiler;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ public function testCompleteExistingDefinitionWithNotDefinedArguments()

/**
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
* @expectedExceptionMessage Unable to autowire type "Symfony\Component\DependencyInjection\Tests\Compiler\CollisionInterface".
* @expectedExceptionMessage Unable to autowire argument of type "Symfony\Component\DependencyInjection\Tests\Compiler\CollisionInterface" for the service "a".
*/
public function testTypeCollision()
{
Expand Down Expand Up @@ -178,6 +178,20 @@ public function testOptionalParameter()
$this->assertEquals('a', $definition->getArgument(1));
$this->assertEquals('foo', $definition->getArgument(2));
}

public function testNoAutowiringTag()
{
$container = new ContainerBuilder();

$container->register('foo', __NAMESPACE__.'\Foo');
$barDefintion = $container->register('bar', __NAMESPACE__.'\Bar');
$barDefintion->addTag(AutowiringPass::NO_AUTOWIRING);

$pass = new AutowiringPass();
$pass->process($container);

$this->assertCount(0, $container->getDefinition('bar')->getArguments());
}
}

class Foo
Expand Down
2 changes: 2 additions & 0 deletions src/Symfony/Component/HttpKernel/Kernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ abstract class Kernel implements KernelInterface, TerminableInterface
protected $name;
protected $startTime;
protected $loadClassCache;
protected $containerAutowiring = true;

const VERSION = '2.8.0-DEV';
const VERSION_ID = 20800;
Expand Down Expand Up @@ -552,6 +553,7 @@ protected function getKernelParameters()
'kernel.bundles' => $bundles,
'kernel.charset' => $this->getCharset(),
'kernel.container_class' => $this->getContainerClass(),
'container.autowiring' => $this->containerAutowiring,
),
$this->getEnvParameters()
);
Expand Down
0