nassau/registry-compiler

该包已被弃用且不再维护。没有推荐替代包。

1.2 2018-02-05 12:04 UTC

This package is auto-updated.

Last update: 2024-05-03 10:24:54 UTC


README

nassau.registry 标签添加到服务中,它将接收其他带有您选择的名称标签的服务集合。类似于事件分发器、缓存预热器、twig 扩展等。

如果您曾经创建了一个 CompilerPass 并在内部使用了 $containerBuilder->findTaggedServiceIds(),您可能可以用 nassau/registry-compiler 来替换它。

安装

composer require nassau/registry-compiler

将编译器传递添加到您的包之一。由于它可能在您的某些依赖项中使用,建议使用传递的 register 方法来确保只注册一个实例。

# somewhere inside AcmeBundle.php

	public function build(ContainerBuilder $container)
	{
		(new RegistryCompilerPass)->register($container);
	}

用法

services:
    foobar.manager:
        class: FooBaringManager
        tags:
            -
            # This is the starting point for the lib:

              name: nassau.registry

            # Collect all services tagged with this value:
            #
            # This is a required attribute

               tag: foobaring.provider

            # Every tagged service will be passed to this method. It’s signature needs to be:
            #
            # `public function addFooBarProvider($index, $foobar)`
            #
            # This is an optional attribute, defaults to "set", as per symfonys conventions
            #
            # Setting this to null/empty value will automatically enable the `use_collection`
            # option below.

              method: addFooBarProvider

            # Instead of having each tagged service passed to your setter, you may choose to
            # get an iterator with all the objects in one call. This will be an `ArrayObject`
            # and your signature needs to be
            #
            # `public function addFooBarProviders(\ArrayObject $items)`

              use_collection: false

            # You may decide to use a constructor injection instead of a setter when using the
            # above option. In this case set the method to null, so the compiler won’t add any
            # `calls` to your service definition. Instead, setup your dependency yourself:
            #
            # foo:
            #   arguments: [ @foo.providers ]
            #   tags:
            #     - { name: nassau.registry, use_collection: providers, method: ~ }
            #

              use_collection: collection

            # Choose an order in which the services will be provided
            #   natural (default): just the way the container returns them
            #   priority: define a priority field to control the order (high to low)
            #   indexed: don’t order them, you’ll be using a key => value anyway

              order: indexed

            # If you choose the 'priority' order, you may override the name of the
            # attribute used to determine the items priority. You may also set the default
            # value if the field isn’t set on an item.
            #
            # Default: priority

              priority_field: weight
              default_priority: 1024

            # If you choose the 'indexed' order, you may override the name of the
            # attribute used to determine the items key. This attribute is required
            # to be present on the related service tag.
            #
            # Default: alias

              alias_field: foobar_name

            # And finally, you’d probably like to restrict services to be of
            # certain class or implementing an interface:

              class: FooBaringInterface

    foobar.provider.cache:
        class: CachedFooBaring
        public: false
        tags:
            -
            # First match the registrys tag name:

              name: foobaring.provider

            # Then provide any details needed. In this case, the name is required since
            # the order is set to "indexed". The "alias" attribute was set to "foobar_name"

              foobar_name: cache

            # This will result in calling method `addFooBarProvider` on `foobar.manager`
            # service with parameters: "cache" and `foobar.provider.cache` instance.

示例

给定一个接口

interface FooBarInterface {
    public function makeFooBar($input);
}

您可能需要将实现分割到多个类中。也许它像是一个 monolog 处理器——每个都完成自己的任务然后继续。为了简化使用,您创建了一个链式实现,这样使用 FooBarInterface 的类就不知道细节

class ChainFooBar implements FooBarInterface {

    /** @var FooBarInterface[] **/
    private $collection = [];

    public function addFooBar($name, FooBarInterface $fooBar) {
        $this->collection[$name] = $fooBar;
    }

    public function makeFooBar($input) {
        foreach ($this->collection as $fooBar) {
            $fooBar->makeFooBar($input);
        }
    }
}

到目前为止一切顺利。现在您只需要使用容器将每个实现连接起来。只要您有固定数量的实现,您就可以使用调用

services:
  foo_bar.chain:
    class: ChainFooBar
    calls: 
      - ['addFooBar', [ 'alpha', '@foo_bar.alpha' ] ]
      - ['addFooBar', [ 'bravo', '@foo_bar.bravo' ] ]

但是这会变得很混乱,而且没有简单的方法来添加更多实现,尤其是如果您只是制作库/架构,实现取决于开发者。

这就是 nassau.registry 发挥作用的地方。您不必手动将实现连接到链,只需注册一个标签,任何服务都可以将其自己连接起来

services:
  foo_bar.chain:
    class: ChainFooBar
    tags:
      - name: nassau.registry
        tag: foo_bar
        method: addFooBar
        order: indexed
        class: FooBarInterface

  foo_bar.alpha:
    class: FooBarAlpha
    tags:
      - name: foo_bar
        alias: alpha