Symfony控制器中服务的Getter方法

时间:2018-09-11 14:17:54

标签: symfony

在控制器中为常用服务设置服务获取器是一种好习惯吗?例如,我的意思是:

class SomeController Extends Contorller {

      private function getSomethingManager()
      {
           return $this->get('myvendorname.something.manager');
      }

}

2 个答案:

答案 0 :(得分:1)

您的示例有点令人困惑,因为您可以直接在控制器上使用Doctrine服务。如果使用“自动装配”功能,则可以将其插入“动作”中。

public function test(EntityManagerInterface $em) {

}

然后您已经注入了实体管理器,或者可以通过以下方法在控制器上加载它:

$this->getDoctrine()->getManager()

所以这不是一个很好的例子。使用autowire时,所有类都注册为服务,您可以使用它。

对于数据库查询,您必须使用实体和存储库。

https://symfony.com/doc/current/doctrine.html

答案 1 :(得分:1)

如果您高于Symfony 3.3,则可以使用Service Locater。您在“服务定位器”类中列出了所有常用服务。当您需要从任何地方获取特定服务时(例如,控制器,命令,服务等),您要做的就是注入ServiceLocator类并通过ServiceLocator:locate获取所需的服务。

这非常简单且有用。它还可以帮助您减少依赖注入。看看上面链接中的完整示例。

class ServiceLocator implements ServiceLocatorInterface, ServiceSubscriberInterface
{
    private $locator;

    public function __construct(ContainerInterface $locator)
    {
        $this->locator = $locator;
    }

    public static function getSubscribedServices()
    {
        return [
            ModelFactoryInterface::class,
            CalculatorUtilInterface::class,
            EntityManagerInterface::class,
            AnotherClass::class,
            AndAnother::class,
        ];
    }

    public function get(string $id)
    {
        if (!$this->locator->has($id)) {
            throw new ServiceLocatorException(sprintf(
                'The entry for the given "%s" identifier was not found.',
                $id
            ));
        }

        try {
            return $this->locator->get($id);
        } catch (ContainerExceptionInterface $e) {
            throw new ServiceLocatorException(sprintf(
                'Failed to fetch the entry for the given "%s" identifier.',
                $id
            ));
        }
    }
}

这是您的使用方式:ServiceLocator->locate(AnotherClass::class);