2

I'm dumb and this is embarrassing, but I'm trying to figure out how I properly use a method from a class in other parts of my code. I need to understand the Drupal way, if not just the php way.

I have a class like this...

namespace Drupal\module_name\Utilities; use GuzzleHttp\Exception\RequestException; use Drupal\Core\Logger\LoggerChannelFactory; use Drupal\Core\Messenger\MessengerInterface; use Symfony\Component\DependencyInjection\ContainerInterface; use GuzzleHttp\ClientInterface; use Drupal\Core\Config\ConfigFactoryInterface; use Drupal\Core\DependencyInjection\ContainerInjectionInterface; class Example implements ContainerInjectionInterface { private $client; protected $loggerFactory; protected $messenger; protected $config; public function __construct( LoggerChannelFactory $loggerFactory, MessengerInterface $messenger, ClientInterface $client, ConfigFactoryInterface $config ) { $this->loggerFactory = $loggerFactory->get('simple_mailchimp'); $this->messenger = $messenger; $this->client = $client; $this->config = $config->get('module_name.settings'); } public static function create(ContainerInterface $container) { return new static( $container->get('logger.factory'), $container->get('messenger'), $container->get('http_client'), $container->get('config.factory') ); } public function request() { return 'whatever'; } } 

What's the proper way to use this class somewhere else? For instance, in another module, I want to call the request() method shown above.

 $example = new Example(); $x = $example->request(); 

This doesn't work, as shown above. I get this...

ArgumentCountError: Too few arguments to function Drupal\module_name\Utilities\Example::__construct(), 0 passed... and exactly 4 expected 

(Even though it seemed to have worked at one time.)

That said, what's the right way to go about this with Drupal, or in general, I guess?

4
  • 2
    You need to inject this service into the class you want to use it in. This is not a Drupalism; this is general programming. drupal.org/docs/drupal-apis/services-and-dependency-injection/… Commented Apr 7, 2021 at 18:31
  • 1
    And look here as well: drupal.stackexchange.com/q/195165/15055. You can't use dependency injection in your custom class without defining it as a service. Then you don't need the implements ContainerInjectionInterface { part. Then its just class Example { and in there create and construct. Commented Apr 7, 2021 at 19:57
  • 1
    Like git.drupalcode.org/project/twigsuggest/-/blob/8.x-1.x/… (the service) and git.drupalcode.org/project/twigsuggest/-/blob/8.x-1.x/src/Utils/… (the class) for example. Commented Apr 7, 2021 at 20:01
  • Thanks everyone. This was all helpful. I know services and dependency injection isn't just a "Drupalism." But I was afraid I was missing something Drupal-specific here. In the end, I refactored my code to inject the service as suggested. Then I got the same error message. At which point, I realized I need to add the arguments to my service in the yml file - ['@logger.factory', '@messenger', '@http_client', '@config.factory'] Commented Apr 7, 2021 at 21:58

1 Answer 1

4

If you want to instantiate a class implementing ContainerInjectionInterface you have to use the Drupal class resolver:

$example = \Drupal::classResolver(Example::class); $x = $example->request(); 

The preferred way though is to use a service class instead and inject other services directly as container arguments, as @Kevin commented.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.