2

I've got a class hierarchy where I need to be able to instantiate different objects within the hierarchy. Instead of using global functions, I'd like to use injected services from the container via $this within those objects.

When researching this, it seems as though the only examples I can find involve creating a service, such as Dependency injection in a custom class. However, I don't need a new service. If I did create one, wouldn't I need to create one for every class within the hierarchy so that they could be instantiated? This seems excessive.

If my parent class implements ContainerInjectionInterface and I have a create() method to inject the services, can I just instantiate the objects this way, or is it bad practice?

$thing = OneOfMySubClasses::create(\Drupal::getContainer(), ...);

3

Not sure how many classes/services you have, but the main point for having services is to have the dependencies injected. Drupal core alone has probably 100+ services, so I wouldn't worry too much about adding 10 or so more.

Using ContainerInjectionInterface is also fine, if you do that, you can use the class_resolver service that will take care of doing that, it also accepts both a class implementing that interface as well as a service name.

https://api.drupal.org/api/drupal/core%21lib%21Drupal.php/function/Drupal%3A%3AclassResolver/8.4.x

Depending on how you use/configure/decide which of your classes to you, you could also make a plugin type and make them plugins, e.g. like block plugins or field formatters.

  • Looks like \Drupal::classResolver()->getInstanceFromDefinition(OneOfMySubClasses::class) is only useful if you don't have anything outside of the container to pass to the constructor. If you do, you have to call create() yourself to feed in the other parameters. – colan Oct 12 '17 at 20:43
  • This also means it's not possible to to implement ContainerInjectionInterface, because that create() method doesn't accept other parameters. It only accepts the container. – colan Dec 6 '17 at 20:01
  • Correct, but there are workarounds for that, like using setter methods on the created object. You can also implement your own logic for that, there are separate plugins plugins with dependencies and entity handlers with dependencies – Berdir Dec 7 '17 at 19:36

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.