使用ZF2服务管理器覆盖实现

3
假设在我的Zf2应用程序中,我有一个通过服务管理器检索的类A
'service_manager' => [
    'invokables' => [
        'A' => 'A'
    ]
]

如果每次检索类 A 时,我希望返回 A 的装饰器 B,则可以使用委托工厂。
现在如果我想以这种方式装饰所有实现接口 I 的类,无论何时从服务管理器中检索它们,该怎么办?初始化程序在这里似乎没有帮助,因为它们无法替换从服务管理器检索的实现。
有没有一种方法可以做到这一点?非常感谢任何建议。

抽象工厂?您可以在canCreateServiceWithName函数中检查服务是否实现了I - Ankh
我无法更改服务管理器声明中A的声明方式。当检索A类时,我只需要修改服务管理器返回的类。 - marcosh
1个回答

0

你可以创建一个自定义插件管理器,负责创建类型为I的服务。

这将允许您为每个服务(或抽象工厂)注册自定义工厂,并仍然装饰与服务管理器注册的原始服务。

下面的配置可能有助于解释。

return [
    'service_manager' => [
        'invokables' => [
            'A' => 'A',
            'B' => 'B',
        ]
    ],
    'foo_plugin_manager' => [
        'factories' => [
            'B' => 'FactoryB'
        ],
        'abstract_factories' => [
            'AbstractFactoryThatDecoratesAll',
        ]
    ],
];

这种方法的问题在于,您需要更新对任何调用的引用。

$serviceManager->get('A') 

使用

$serviceManager->get('FooPluginManager')->get('A')

谢谢Alex,但是我觉得我不能这样做。因为我正在使用一个外部库,它直接使用服务管理器,所以我不能将插件管理器引入到项目中。 - marcosh
@marcosh 有没有什么原因,你不能为每个服务注册装饰器? - AlexP
因为我正在开发一个可能会被其他人使用的模块,所以我不知道我将需要装饰哪个服务。我想仅暴露接口,并使用它来执行装饰。 - marcosh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接