bangpound/callable-compiler-pass

在 Symfony 中创建编译器过程而不定义另一个类

1.0.0 2016-03-11 01:49 UTC

This package is auto-updated.

Last update: 2024-09-12 03:36:04 UTC


README

使用此 CompilerPassInterface 实现来 创建编译器过程,在 Symfony 中创建编译器过程而不定义另一个类。

使用方法

您应该在需要实例化容器编译器过程以修改 Symfony 依赖注入容器的任何地方使用此类。对于典型的 Symfony 应用程序,这通常发生在扩展包中。

没有 CallableCompilerPass,您的扩展包类将这样添加编译器过程

<?php
namespace My\Bundle\CoolBundle;

use Symfony\Component\HttpKernel\Bundle\Bundle;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use My\Bundle\CoolBundle\DependencyInjection\Compiler\AddMyStuffPass;

class MyCoolBundle extends Bundle
{
    public function build(ContainerBuilder $container)
    {
        parent::build($container);

        $container->addCompilerPass(new AddMyTaggedServicesPass());
    }
}

有了 CallableCompilerPass,您就可以跳过创建 AddMyTaggedServicesPass,并在扩展包的构建方法中定义编译器过程

<?php
namespace My\Bundle\CoolBundle;

use Symfony\Component\HttpKernel\Bundle\Bundle;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Bangpound\Symfony\DependencyInjection\CallableCompilerPass;

class MyCoolBundle extends Bundle
{
    public function build(ContainerBuilder $container)
    {
        parent::build($container);

        $container->addCompilerPass(new CallableCompilerPass(
            function (ContainerBuilder $container) {
                if (!$container->has('my_cool.service')) {
                    return;
                }

                $definition = $container->findDefinition('my_cool.service');

                $taggedServices = $container->findTaggedServiceIds(
                    'my_cool.service_addition'
                );

                foreach ($taggedServices as $id => $tags) {
                    $definition->addMethodCall(
                        'addThing', array(new Reference($id))
                    );
                }
            }
        ));
    }
}

当在 Symfony 2.8 和 3.0 中使用新的 MicroKernelTrait 开发 Symfony 应用程序时,CallableCompilerPass 的实用性最为明显。

<?php

use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Kernel;

class AppKernel extends Kernel
{
    use MicroKernelTrait;

    public function registerBundles()
    {
        $bundles = array(
            new Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
        );

        return $bundles;
    }

    protected function configureContainer(ContainerBuilder $c, LoaderInterface $loader)
    {
        $c->addCompilerPass(new CallableCompilerPass(function (ContainerBuilder $container) {
            if (!$container->has('my_cool.service')) {
                return;
            }

            $definition = $container->findDefinition('my_cool.service');

            $taggedServices = $container->findTaggedServiceIds(
                'my_cool.service_addition'
            );

            foreach ($taggedServices as $id => $tags) {
                $definition->addMethodCall(
                    'addThing', array(new Reference($id))
                );
            }
        });
    }
}

在微内核中,您还可以使用 CallableCompilerPass 来删除不需要但默认由 Symfony FrameworkBundle 添加的服务,例如。