matthiasnoback/symfony-bundle-plugins

允许 Symfony 扩展包拥有插件

v1.1.1 2016-01-19 18:38 UTC

This package is auto-updated.

Last update: 2024-08-29 04:09:05 UTC


README

由 Matthias Noback 编写

Build Status Coverage Status

此包通过引入扩展包的插件系统来帮助您创建可扩展的扩展包。每个扩展包插件都可以定义自己的服务和配置。这基本上使您的扩展包符合开/闭原则。

设置

通过运行以下命令在项目中安装此库:

composer require matthiasnoback/symfony-bundle-plugins

示例

首先,您的扩展包应该扩展 BundleWithPlugins。您需要实现 getAlias 方法。它应该返回您扩展包配置键的名称(例如,它将在 config.yml 中使用)。

use Matthias\BundlePlugins\BundleWithPlugins;

class DemoBundle extends BundleWithPlugins
{
    protected function getAlias()
    {
        return 'demo';
    }
}

扩展包的每个插件都应该实现 BundlePlugin

use Matthias\BundlePlugins\BundlePlugin;
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;

class FooPlugin implements BundlePlugin
{
    public function name()
    {
        return 'foo';
    }

    public function load(
        array $pluginConfiguration, 
        ContainerBuilder $container
    ) {
        // load specific service definitions for this plugin,
        // just like you would do in a bundle extension
        
        $loader = new YamlFileLoader($container, new FileLocator(__DIR__));
        $loader->load('foo.yml');
        
        // $pluginConfiguration contains just the values that are relevant 
        // for this plugin
    }

    public function addConfiguration(ArrayNodeDefinition $pluginNode)
    {
        // add plugin-specific configuration nodes, 
        // just like you would do in a bundle extension
    
        $pluginNode
            ->children()
                ->scalarNode('foo')
                ->isRequired()
            ->end();
    }
}

当在您的 AppKernel 类中实例化此扩展包时,您可以提供任意数量的 BundlePlugin 实例

class AppKernel extends Kernel
{
    public function registerBundles()
    {
        return array(
            ...,
            new DemoBundle(array(new FooPlugin()))
        );
    }
}

如果某些插件是必需的,只需引入一个 CorePlugin 并确保它通过覆盖您的扩展包的 alwaysRegisteredPlugins() 方法始终被注册

class DemoBundle
{
    ...
    
    protected function alwaysRegisteredPlugins()
    {
        return array(new CorePlugin());
    }
}

注册编译器传递

当扩展包插件需要注册编译器传递时,它可以在其 build() 方法中这样做。

class FooPlugin implements BundlePlugin
{
    ...
    
    public function build(ContainerBuilder $container)
    {
        $container->addCompilerPass(...);
    }
}

启动插件

每当主扩展包启动时,插件也允许进行一些运行时初始化。它们可以在它们的 boot() 方法中这样做。那时,完全初始化的服务容器是可用的

class FooPlugin implements BundlePlugin
{
    ...
    
    public function boot(ContainerInterface $container)
    {
        // runtime initialization (will run when the kernel itself is 
        // booted)
    }
}

简单插件

如果您的插件相当简单(即只需要一个 load() 方法),只需让插件类扩展 SimpleBundlePlugin,它包含您不需要的接口方法的存根实现。

感谢

感谢 @dennisdegreef 为恢复此项目的测试套件。