Maneira correta de chamar um serviço em um controlador

10

Eu sou novo em serviços (e drupal 8!) E estou tentando descobrir serviços. Eu acho que talvez eu esteja apenas criando um desatualizado. O que eu quero fazer é tornar meu 'hello generator' um serviço e chamá-lo em outro controlador com o seguinte:

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

espaço para nome 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'
karl
fonte
Você pode seguir o documento . É a maneira correta de chamar um serviço em um controlador
MrD

Respostas:

22

Existem 3 perguntas aqui:

  1. Como criar um controlador?
  2. Como criar um serviço?
  3. Como usar serviços em um controlador?

1. Crie um controlador

1.1 Adicione uma classe de controlador - você fez isso. Para outros, consulte a documentação do Drupal

1.2 Adicione um arquivo de roteamento - parece que está faltando no seu código:

my_module.routing.yml

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

consulte a documentação do Drupal

2. Crie um serviço

2.1 Adicione uma classe de serviço - você fez.

2.2 Adicionar um arquivo de roteamento - você o fez, embora ele contenha código extra que pertença ao arquivo de roteamento. Isso é tudo que você precisa:

my_module.services.yml

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

consulte a documentação do Drupal

3. Use serviços em um controlador

Você fez isso. Aqui está uma referência para outras pessoas:

3.1 Substituir o create()método

A classe do controlador herda esse método de class ControllerBase. Seu papel é criar o objeto do controlador. Observe o argumento do método: é passado o contêiner de serviços. Extraia os serviços necessários e passe-os para o construtor:

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 Inicializar serviços em __construct()

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

3.3 Comece a usar os serviços

zendka
fonte
4
Eu gostaria que a documentação oficial fosse mais desse estilo ou que tivesse pelo menos alguns artigos de visão geral. Curto e conciso com um exemplo genérico facilmente traduzido para o aplicativo real.
Nicolaj
Não se esqueça: use Symfony \ Component \ DependencyInjection \ ContainerInterface; na classe do controlador
Atep 27/02
Embora eu concorde totalmente com o comentário de @ Nicolaj, isso não está funcionando para mim ... e nem estou tentando usar um serviço personalizado! Tudo o que eu quero fazer é criar uma variável de membro da classe que mantenha um objeto de conexão de banco de dados estático. Estou acostumado a usar sistemas em que o pool de conexões e nunca criar mais conexões do que você precisa é a norma. Então, como eu implementaria algo semelhante em um controlador / formulário do Drupal?
Kenny83 8/04
Você pode abrir outra pergunta @ Kenny83, mas já consultou api.drupal.org/api/drupal/core%21lib%21Drupal.php/function/… ? Com isso, você pode fazer algo assim: gist.github.com/glaux/f4f1517563ddb57fb98b9213802c1569
Nicolaj
@ Nicolaj LOL, obrigado por apontar o parceiro óbvio: P Estou bem ciente do serviço de banco de dados principal e é isso que estou tentando retornar do meu create()método. Eu suponho que você não teria dito que, embora se eu não tivesse perdido alguma coisa outra coisa que deveria ter sido óbvio ... Eu acho que o serviço faz objetos de conexão piscina?
Kenny83 8/04