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

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.

Not the answer you're looking for? Browse other questions tagged or ask your own question.