1

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?

2 Answers 2

1

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.)

2
  • In this case we no need to add "use Drupal\custom_form1\Services\TestService;" in our file?
    – RaMeSh
    Commented Feb 21, 2022 at 7:49
  • 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.
    – apaderno
    Commented Feb 21, 2022 at 9:29
3

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.

1
  • 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.
    – sonfd
    Commented Feb 19, 2022 at 15:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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