Score:1

How can I inject dependencies based on conditions?

cn flag

I am creating one custom form and in this form I need to use one service which are there in another module. I need to use that dependency injection based on condition which are there in configuration.

Conditions in Config Form:

  1. Use Custom1 Form
  2. Use Custom2 Form

If “Use Custom1 Form” enabled, then I need to use dependency injection.

namespace Drupal\test\Form;

use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
use Symphony\Component\DependencyInjection\ContainerInterface;
use Drupal\custom_form1\Services\TestService;

/**
 * Test forms.
 */
class TestForm extends ConfigFormBase {

  /**
   * PinCodeRegistration Object.
   *
   * @var Drupal\custom_form1\Services\TestService;
   */
  protected $TestService;

  /**
   * Constructs a new pin code multistep form.
   *
   * @param Drupal\custom_form1\Services\TestService $test_service
   *   The service handler.
   */
  public function __construct(TestService $test_service) {
    $this->TestService = $test_service;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('custom_form1.form1_services')
    );
  }
}

How can I add use Drupal\custom_form1\Services\TestService; based on conditions?

If the custom_form1 module isn't installed, I get an error. Any Idea how we need to avoid error and added dependency based on conditions?

Score:3
de flag

Dependencies cannot be added conditionally based on functionality within the class, as the injection happens during instantiation of the class, and is already complete before class methods can be called. Instead, you inject both services, and use whichever one you need when you need it. Or you can call the service you need statically using \Drupal::service() when you actually need it, though it is preferable to use dependency injection when in class context over calling services statically.

sonfd avatar
in flag
Exactly. And in a situation where you need to use a service from a module that isn't a hard dependency of your module, i.e. the module may not be installed, it's perfectly acceptable to not use dependency injection.
Score:1
us flag

The question doesn't make it explicit, but since the question mentions getting an error when another module isn't installed, I take that the condition is when the module is installed. In that case, the module can simply use the following code.

public function __construct(TestService $test_service = NULL) {
  $this->testService = $test_service;
}

public static function create(ContainerInterface $container) {
  return new static(
    $container->has('custom_form1.form1_services') ? $container->get('custom_form1.form1_services') : NULL
  );
}

In this case, the class in your module should be ready not to get any class instance. Alternatively, your module could implement a simplified version of the service, which implement the same interface, and use code similar to the following one.

public function __construct(TestServiceInterface $test_service = NULL) {
  $this->testService = $test_service;
}

public static function create(ContainerInterface $container) {
  return new static(
    $container->has('custom_form1.form1_services') ? $container->get('custom_form1.form1_services') : $container->get('mymodule.form1_services')
  );
}

This assumesTestService implements an interface that can be implemented from the simplified service. (It also assumes it's possible to implement a simplified service.)

RaMeSh avatar
cn flag
In this case we no need to add "use Drupal\custom_form1\Services\TestService;" in our file?
apaderno avatar
us flag
It's preferable to use it for the interface, if there is one. Yes, you need it. PHP doesn't check the class exists when `use Drupal\custom_form1\Services\TestService;` is used, but when the class instance is used.
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.