Syfmony-引导时加载服务 [英] Syfmony - load service on boot

查看:123
本文介绍了Syfmony-引导时加载服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发布了另一个问题,试图查找一种在定制帮助器"类中的控制器外部静态访问存储库类的方法.

I posted another question trying to find a way to statically access a repository class outside of a controller in a custom "helper" class.

到目前为止,我弄清楚如何实现此目标的唯一方法是使用下面的代码.如果有人想陷入有关最佳实践"或设计模式"的其他问题,请这么做.

So far the only way I have figured out how to achieve this is using the code below. If anyone wants to chime into the other question about "best practice" or "design patterns" please do.

我打开了这个问题,以寻求在symfony引导时加载单例服务(?)的最佳方法,以便其他类可以静态访问它而无需任何依赖项注入.我没有找到任何正式文档或常见做法的运气.我知道单例是一种反实践,但是这种方法是不是最好的方法,还是有一个更理想的解决方案?

I opened this question to seek the best method on having a singleton service (?) loaded when symfony boots so other classes can access it statically without any dependency injection. I haven't had much luck on finding any official docs or common practices. I know singleton is anti practice, but is the method below the best way, or is there a more ideal solution?

services.yml

parameters:
    entity.device: Asterisk\DbBundle\Entity\Device
services:
    asterisk.repository.device:
    class: Asterisk\DbBundle\Entity\Repositories\DeviceRepository
    factory: ["@doctrine.orm.asterisk_entity_manager", getRepository]
    arguments:
        - %entity.device%
    tags:
        - {name: kernel.event_listener, event: kernel.request, method: onKernelRequest}

DeviceRepository

class DeviceRepository extends \Doctrine\ORM\EntityRepository
{
    /** @var  ExtendedEntityRepository */
    protected static $instance;

    public function __construct(EntityManager $entityManager, ClassMetadata $class)
    {
        parent::__construct($entityManager, $class);

        if(static::$instance instanceof static == false)
            static::$instance = $this;
    }

    public static function getInstance()
    {
        return static::$instance;
    }

    public function onKernelRequest($event)
    {
        return;
    }
}

推荐答案

很高兴看到您不再跑来跑去.

Glad to see you are not running around anymore.

您的方法无法奏效,除非有人首先将存储库从容器中取出,以便对self :: $ instance进行初始化.但是您真的不想这样做.超级hacky.

Your approach is not going to work unless someone grabs the repository out of the container first so self::$instance is initialized. But you really don't want to do this anyways. Super hacky.

您要将存储库服务注入内核侦听器.试图使存储库充当内核侦听器并不是一个好的设计.因此,只需为您的存储库提供一项服务,然后为侦听器提供第二项服务即可.乍一看似乎有些奇怪,但实际上在实践中效果很好,这就是S2的设计方式.

You want to inject the repository service into your kernel listener. Trying to make the repository act as a kernel listener is just not a good design. So just make a service for your repository and then a second one for the listener. It may seem a bit strange at first but it really does work well in practice and it's the way S2 is designed.

如果由于某种原因,您必须必须全局访问容器,那么请注意,您的内核是全局定义的(请查看app.php),并且其中包含getContainer方法

If for some reason you are stuck with the notion that you have to be able to access the container globally then be aware that your kernel is defined globally(take a look at app.php) and it has a getContainer method in it.

$repo = $_GLOBAL['kernel']->getContainer()->get('asterisk.repository.device');

但是同样,没有必要这样做.

But again, there should be no need to do this.

=============================

==============================

更新-您似乎正试图使用​​侦听器功能来设置单例.您应该尝试避免单例,但是如果您确实认为需要单例,则可以使用对内核的全局访问:

Update - It looks like you are trying to use the listener functionality just to setup singletons. You should try to avoid singletons but if you really think you need them then the global access to the kernel can be used:

class DeviceRepository extends \Doctrine\ORM\EntityRepository
{
  /** @var  ExtendedEntityRepository */
  protected static $instance;

  public static function getInstance()
  {
    if (!static::$instance) {
        static::$instance = $_GLOBAL['kernel']->getContainer()->get('asterisk.repository.device');
    }
    return static::$instance;
  }

设计欠佳,但至少它摆脱了侦听器的攻击,并且避免了在实际需要之前创建存储库.它也意味着您可以从命令访问存储库(调用命令时未设置侦听器).

Poor design but at least it get's rid of the listener hack and it avoids creating the repository until it's actually needed. It aslo means you can access the repository from commands (listeners are not setup when commands are called).

这篇关于Syfmony-引导时加载服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆