6

I have a custom module (my_module); Inside this module I have a custom class (MyClass), where I want to use a Drupal service (file_system).

This is my code.

src/MyClass.php

namespace Drupal\my_module;

use Drupal\Core\File\FileSystem;

class MyClass {
  public function __construct(FileSystem $file_system) {
  }

  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('file_system')
    );
  }
}

When I instantiate this class (in a controller for example), I get an error.

$my_class = new MyClass();

TypeError: Argument 1 passed to Drupal\my_module\MyClass::__construct() must be an instance of Drupal\Core\File\FileSystem, none given

What is wrong in my code?

13

DI requires a bit more effort than that - you haven't told the system about your class; the DI container doesn't know that you've called new MyClass(), and it can't get involved.

You need to create a Service, which you can make depend on other available services, instances of which will be passed to your class using the static create method pattern you're already using.

In this case, that's probably as simple as providing your mymodule.services.yml and adding:

my_service:
    class: Drupal\my_module\MyClass
    arguments: ['@file_system']

When you've correctly registered the class with the system, you'll get an instance of it like so (if you need it in a global function):

$foo = Drupal::service('my_service');

Or if you're consuming it in a container aware class, then you can inject it just like any other service.

  • Thank you for your answer. In $foo, i will get an instance of MyClass ? If i write : $foo1 = Drupal::service('my_service'); $foo2 = Drupal::service('my_service'); I will get 2 distinct instances ? – CamelCode Mar 18 '16 at 9:01
  • Symfony services are singletons as far as I know, you probably want to create a factory if you need different instances – Clive Mar 18 '16 at 9:05
  • 1
    Ok so, declaring a class as a service is the only way of using DI insite it ? – CamelCode Mar 18 '16 at 9:08
  • 1
    As far as utility classes go, yes. Controllers are different, for example – Clive Mar 18 '16 at 9:12
  • 1
    @Clive how does the form system does it? I mean when creating a custom configuration form the create method can have $container->get('current_user'), as DI. But is ConfigFormBase a service ? or how is actually being injected? – awm Oct 9 '17 at 20:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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