在控制器中调用服务的正确方法


10

我是服务(以及drupal 8!)的新手,正在尝试弄清楚服务。我认为也许我只是在以过时的方式进行创建。我想要做的是使“ hello generator”成为服务,并使用以下命令在另一个控制器中调用它:

DBController.php

namespace Drupal\db\Controller;

use Drupal\Core\Controller\ControllerBase;
use Drupal\db\DbServices\HelloGenerator;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Response;


class DBController extends ControllerBase
{
private $helloGenerator;

public function __construct(HelloGenerator $x) {
    $this->helloGenerator = $x;
}
public function say($count) {
    $hello = $this->helloGenerator->getHello($count);

    return new Response($hello);
}

public static function create(ContainerInterface $container) {
    $x = $container->get('db.hello_generator');
    return new static ($x);
}
}

HellGenerator.php

命名空间Drupal \ db \ DbServices;

class HelloGenerator {

public function getHello($count) {
    $foo = 4 + 4 + 4;
    return $foo . ' ' . $count;
}

}

db.services.yml

services:
  db.hello_generator:
     class: Drupal\db\DbServices\HelloGenerator

db.db_says:
  path: /db/says/{count}
  defaults:
    _controller: '\Drupal\db\Controller\DBController::say'
  requirements:
    _permission: 'access content'

您可以关注document。这是在控制器中调用服务的正确方法
MrD

Answers:


22

这里有3个问题:

  1. 如何创建控制器?
  2. 如何创建服务?
  3. 如何在控制器中使用服务?

1.创建一个控制器

1.1添加一个控制器类 -做到了。对于其他人,请参阅Drupal文档

1.2添加路由文件 -您的代码中似乎缺少此文件

my_module.routing.yml

my_module.my_route_name:
  path: '/my/path'
  defaults:
    _controller: '\Drupal\my_module\Controller\MyController::myAction'
  requirements:
    _permission: 'access content'

请参阅Drupal文档

2.创建服务

2.1添加服务类 -您已完成。

2.2添加路由文件 -尽管它包含属于该路由文件的额外代码,但您还是这样做了。这就是您所需要的:

my_module.services.yml

services:
  my_module.my_service:
    class: Drupal\my_module\Service\MyService

请参阅Drupal文档

3.在控制器中使用服务

你做到了。这是其他人的参考:

3.1覆盖create()方法

控制器类从继承此方法class ControllerBase。它的作用是创建控制器对象。观看方法参数:它传递给服务容器。提取所需的服务并将其传递给构造函数:

public static function create(ContainerInterface $container) {
    $my_service = $container->get('my_module.my_service');
    $other_service = $container->get('other_service');

    return new static($my_service, $other_service);
}

3.2初始化服务 __construct()

public function __construct($my_service, $other_service)
{
    $this->my_service = $my_service;
    $this->other_service = $other_service;
}

3.3开始使用服务


4
我希望官方文档更多采用这种风格,或者至少有一些概述文章。简短而简洁的通用示例可轻松转换为实际应用程序。
Nicolaj '18年

一个不要忘记:使用Symfony \ Component \ DependencyInjection \ ContainerInterface; 在控制器课上
Atep

虽然我完全同意@Nicolaj的评论,但这对我来说不起作用...而且我什至不尝试使用自定义服务!我要做的就是创建一个包含静态数据库连接对象的类成员变量。我习惯使用连接池并且从来没有创建超出您需求的连接是正常的系统。那么我将如何在Drupal控制器/表单中实现类似的功能?
Kenny83

您可能想打开另一个问题@ Kenny83,但是您是否看过api.drupal.org/api/drupal/core%21lib%21Drupal.php/function/…?这样,您可以执行以下操作:gist.github.com/glaux/f4f1517563ddb57fb98b9213802c1569
Nicolaj

@Nicolaj LOL感谢您指出令人讨厌的伙伴:P我很清楚核心数据库服务,这就是我要从我的create()方法中返回的内容。我想您不会这么说,尽管如果我没有错过其他事情,那应该是显而易见的……我猜该服务是否会池连接对象?
Kenny83
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.