首页 > 解决方案 > 从 Symfony 中的动态 ID 获取服务

问题描述

我想将服务 ID 集中到实体类中并以这种方式实现我的逻辑:

namespace App\Entity;

interface EntityServiceInterface
{
    public function getServiceId: string;
}
namespace App\Entity;

class EntityA implements EntityServiceInterface
{
    public function getServiceId(): string
    {
        return EntityServiceA::class;
    }
}
namespace App\Entity;

class EntityB implements EntityServiceInterface
{
    public function getServiceId(): string
    {
        return EntityServiceB::class';
    }
}
namespace App\Service;

class EntityServiceA
{
    private LoggerInterface $logger;

    public function __construct(LoggerInterface $logger)
    {
        $this->logger = $logger;
    }

    public function doSomething(): string
    {
        return $this->logger->info('I love Entity A !');
    }
}
namespace App\Service;

class EntityServiceB
{
    private LoggerInterface $logger;

    public function __construct(LoggerInterface $logger)
    {
        $this->logger = $logger;
    }

    public function doSomething(): string
    {
        return $this->logger->info('I love Entity B !');
    }
}
namespace App\Service;

class MyService
{
    private $container;

    /**
     * Injecting ContainerInterface is a bad idea but i need it !
     */
    public function __construct(ContainerInterface $container)
    {
        $this->container = $container;
    }

    public function process($entity): void
    {
        if ($entity instanceof EntityServiceInterface) {
            $service = $this->container->get(entity->getServiceId());

            $service->doSomething();
        }
    }
}

正如我们所知,将 ContainerInterface 注入服务不是一个好主意,但我需要它通过实体类中定义的 ID 来获取我的服务。

如何在不使用 ContainerInterface 的情况下动态获取服务?

在 Symfony 3.4中运行。

如果您需要更多信息,请询问,我会更新问题。

标签: symfonydependency-injectionsymfony-3.4

解决方案


首先,您需要使用 Symfony 3.4 的自动配置标签来标记您的所有 EntityServices。然后,您将需要创建一个作为您自己的私有服务容器的类,并在您的服务定义中引用您的标记服务。然后,不是将整个容器注入到您的 MyService 类中,而是注入您自己的私有容器并在那里获取服务。


推荐阅读