php 使用装饰堆栈来装饰现有服务?

gstyhher  于 2022-12-02  发布在  PHP
关注(0)|答案(1)|浏览(94)

Symfony文档展示了一种非常简洁的方法来创建一个装饰器堆栈:

namespace Symfony\Component\DependencyInjection\Loader\Configurator;

return function(ContainerConfigurator $container) {
    $container>stack('decorated_foo_stack', [
            inline_service(\Baz::class),
            inline_service(\Bar::class),
            inline_service(\Foo::class),
        ])
    ;
};

并将此显示为执行以下操作的替代方法:

// config/services.php
namespace Symfony\Component\DependencyInjection\Loader\Configurator;

return function(ContainerConfigurator $configurator) {
    $services = $configurator->services();

    $services->set(\Foo::class);

    $services->set(\Bar::class)
        ->decorate(\Foo::class, null, 5)
        ->args([service('.inner')]);

    $services->set(\Baz::class)
        ->decorate(\Foo::class, null, 1)
        ->args([service('.inner')]);
};

问题是,“整洁”的方法使服务Foo::class未被修饰。使用原始定义的应用程序不通过堆栈,而是访问原始服务。
在我的例子中,我必须装饰一个名为api_platform.serializer.context_builder的服务。这样做可以创建一个装饰堆栈:

$services->stack(
    'decorated_context_builder',
    [
        inline_service(SupportTicketMessageContextBuilder::class),
        inline_service(LeadContextBuilder::class),
        inline_service(BidContextBuilder::class),
        inline_service(PartnerContextBuilder::class),
        inline_service(WebProfileContextBuilder::class),
        service('api_platform.serializer.context_builder'),
    ]
);

服务是由一个供应商依赖项提供的,并且由该依赖项使用。当它使用注入的api_platform.serializer.context_builder时,它完全忽略了我新创建的decorated_context_builder堆栈。
相反,如果我手动创建堆栈:

$services->set(LeadContextBuilder::class)
        ->decorate('api_platform.serializer.context_builder', priority: 4)
    ;

    $services->set(BidContextBuilder::class)
        ->decorate('api_platform.serializer.context_builder', priority: 3)
    ;

// etc, etc, etc

...如预期的那样工作。
如何使用修饰堆栈来修饰现有的服务定义,以便修饰现有的定义?

2izufjch

2izufjch1#

显然,这对于堆栈装饰器是不可能的,因为它们目前不兼容装饰其他服务,只是为了创建独立的堆栈。

相关问题