在控制器中的一个特定操作中,我想将ConcreteServiceA与ConcreteService B交换以更改行为。因为它们有相同的接口。
您可以配置路由以使用不同的控制器
服务名称
对于每个动作;然后配置一个控制器工厂,以使用配置注入所需的服务。
路由配置可能如下所示。
'router' => [
'routes' => [
'foo' => [
'type' => 'literal',
'options' => [
'route' => '/foo',
'defaults' => [
'controller' => 'MyControllerWithFooService',
'action' => 'actionThatNeedsFooService',
],
],
],
'bar' => [
'type' => 'literal',
'options' => [
'route' => '/bar',
'defaults' => [
'controller' => 'MyControllerWithBarService',
'action' => 'actionThatNeedsBarService',
],
],
],
],
]
然后添加服务和控制器的配置。
'app_config' => [
'MyControllerWithFooService' => [
'service_name' => 'FooService',
],
'MyControllerWithFooService' => [
'service_name' => 'BarService',
],
],
'service_manager' => [
'factories' => [
'FooService' => 'FooServiceFactory'
'BarService' => 'BarServiceFactory'
],
],
'controllers' => [
'factories' => [
'MyControllerWithFooService' => 'MyControllerServiceFactory'
'MyControllerWithBarService' => 'MyControllerServiceFactory'
],
]
这个
MyControllerServiceFactory
可能很简单。
class MyControllerServiceFactory
{
public function __invoke($controllerManager, $name, $requestedName)
{
$sm = $controllerManager->getServiceLocator();
$config = $sm->get('config');
if (empty($config['app_config'][$requestedName])) {
throw new ServiceNotCreatedException('No config set!');
}
$serviceName = $config['app_config'][$requestedName]['service_name'];
$service = $sm->get($serviceName);
return new MyController($service);
}
}