Symfony 工厂: 注入依赖项, 自动装配和绑定参数

3

Symfony文档没有给出Symfony中使用工厂的完整示例

在我的情况下,我有许多不同的服务,生成不同的水果API,比如:

  • BananaApiService
  • AppleApiService
  • PearApiService
  • ..

每个服务都有自己的依赖项,这个依赖项是一些绑定参数:

services:
    _defaults:
        autowire: true
        bind:
            $guzzleClientBanana: '@eight_points_guzzle.client.banana'
            $guzzleClientApple: '@eight_points_guzzle.client.apple'
            ...

服务的例子如下:

# BananaApiService.php

class BananaApiService extends DefaultEndpointService
{
    protected $guzzleClientBanana;

    public function __construct(GuzzleClient $guzzleClientBanana)
    {
        $this->guzzleClientBanana = $guzzleClientBanana;
    }

    public function handleRequest(ApiRequest $apiRequest)
    {
    ...
    }
}

目前我没有使用工厂模式,而是将所有服务传递给管理器的构造函数,这太混乱了,违反了最佳实践:

# ApisManagerService

class ApisManagerService
{
    protected $BananaApiService;
    protected $AppleApiService;
    protected $PearApiService;

    public function __construct(BananaApiService $BananaApiService, 
                                AppleApiService $AppleApiService, 
                                PearApiService $PearApiService)
    {
        $this->BananaApiService = $BananaApiService;
        //...
    }

    public function requestDispatcher(ShoppingList $shoppingList): void
    {
        foreach ($shoppingList->getItems() as $item) {
            switch ($item->getName()) {
                case 'banana':
                    $this->BananaApiService->handleRequest($item);
                    break;
                case 'apple':
                    $this->AppleApiService->handleRequest($item);
                    break;
                //...
            }
        }
    }
}

这个requestDispatcher是通过某些事件订阅者调用的:
class EasyAdminSubscriber implements EventSubscriberInterface
{

    public function triggerApisManagerService(GenericEvent $event): void
    {
        /* @var $entity shoppingList */
        $entity = $event->getSubject();

        if (! $entity instanceof shoppingList) {
            return;
        }

        $this->apisManagerService->requestDispatcher($entity);
    }
}

如何使用Symfony工厂(或其他Symfony方法)使代码更好?

你的水果服务的消费者事先不知道他们需要哪种服务吗? - Cerad
我更新了我的问题以获得更清晰的表述 :) - numediaweb
3
以下是如何以最简洁的方式实现没有Symfony Compiler Pass功能的标记策略模式服务的方法。实现没有Symfony Compiler Pass功能的标记策略模式服务 - BentCoder
1个回答

5
我建议您查看实现特定案例的策略模式。相比于所有服务构造函数注入,这将是一种更为清晰的解决方案,特别是在不需要使用所有服务的情况下 - 使用策略模式,您将仅在应用程序运行时使用所需的服务,并处理它们的特定逻辑。请参考策略模式

当存在一系列调用注入服务的情况时,您的解决方案是适用的。但在某些情况下,只需要一个服务。因此,您的容器中有两个多余的实例。对于“!tagged”配置也是如此。 - Rostyslav Pylypenko
当存在一系列调用注入服务的情况时,您的解决方案是适用的。但在某些情况下,只需要一个服务。因此,您的容器中存在两个多余的实例。同样适用于“!tagged”配置。 - undefined

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