16

I am using the following line in a controller class.

 \Drupal::moduleHandler()->alter('mymodule_myfunction', $plugin_items); 

Pareview.sh is giving me this error message.

\Drupal calls should be avoided in classes, use dependency injection instead.

How should I accomplish this? Do I need to create a constructor, create a method, or a service? If so, what code should the service need? I found an example on "Drupal calls should be avoided in classes, use dependency injection instead" for a case where a service already exists.

2
  • create will overload the parent method - here you can inject the services you need. The constructor will then let you assign those to instance variables in the class, so you can use $this->fooInjectedClass->methodName() Commented Jan 30, 2017 at 16:16
  • Do we already have a question about this? If not, we should really make this a canonical. Commented Jan 30, 2017 at 16:43

1 Answer 1

23

In a controller you inject services by using the service container. For example ModuleHandler:

namespace Drupal\mymodule\Controller; use Drupal\Core\Controller\ControllerBase; use Symfony\Component\DependencyInjection\ContainerInterface; use Drupal\Core\Extension\ModuleHandlerInterface; class MyController extends ControllerBase { /** * The module handler service. * * @var \Drupal\Core\Extension\ModuleHandlerInterface */ protected $moduleHandler; /** * Constructs a MyController object * * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler * The module handler service. */ public function __construct(ModuleHandlerInterface $module_handler) { $this->moduleHandler = $module_handler; } /** * {@inheritdoc} */ public static function create(ContainerInterface $container) { return new static( $container->get('module_handler') ); } 

Then you can avoid \Drupal calls by using the injected service:

$this->moduleHandler->alter('mymodule_myfunction', $plugin_items); 

You can inject any service, existing ones from core/contrib or services you've defined in custom code in a *.services.yml file.

To find a core service name I usually look into core.services.yml, because that's the quickest way when you are working on a drupal project in your IDE.

You can use Drupal Console to list all services, not only from core:

drupal debug:container 

You can also use the Devel module, which allows you to search for a name:

/devel/container/service 
3
  • 1
    This sort of question/answer should be expanded upon I agree, and contributed back to drupal.org docs. There is some there, but I feel real world examples like this always help. Commented Jan 30, 2017 at 17:56
  • 4
    The ControllerBase class already implements the ContainerInjectionInterface interface. There is no need to add implements ContainerInjectionInterface to a class that extends ControllerBase. Commented Feb 25, 2018 at 15:46
  • Right, just noticed the same thing as @kiamlaluno; would be grand to update the answer! Commented Jan 30, 2019 at 14:39

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.