web-dev-qa-db-ja.com

依存関係の注入でカスタムクラスをインスタンス化するにはどうすればよいですか?

私はDIパーティーに比較的新鮮で、依存性注入を正確に使用する方法について頭を悩ませています。要件をサービスの一部として渡すことができることを理解していますが、自分のクラスではどうですか?

言語マネージャーサービスを挿入する以下のクラスがあるとします。

_class Foo implements ContainerInjectionInterface {

  protected $languageManager; 

  public function __construct(LanguageManagerInterface $languageManager) {
    $this->languageManager = $languageManager;
  }

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

new Foo()を呼び出すと、LanguageManagerInterfaceのインスタンスを渡す必要があります。これは通常のコンストラクターメソッドの観点からは理にかなっていますが、そのためには以下のようにクラスをインスタンス化する必要があります。

_$languageManager = \Drupal::service('language_manager');
$foo = new Foo($languageManager)
_

それは私には正しくないと思います。

私が欠けているものはありますか、またはこのクラスは常に依存性注入を利用するためのサービスでなければなりませんか?

2
Jimmyb_1991

ContainerInjectionInterfaceを実装するクラスは、ファクトリメソッドcreate()を呼び出すことによってインスタンス化されます。

参照Drupal\Core\DependencyInjection\ClassResolver

/**
 * Implements the class resolver interface supporting class names and services.
 */
class ClassResolver implements ClassResolverInterface, ContainerAwareInterface {
  use DependencySerializationTrait;
  use ContainerAwareTrait;

  /**
   * {@inheritdoc}
   */
  public function getInstanceFromDefinition($definition) {
    if ($this->container->has($definition)) {
      $instance = $this->container->get($definition);
    }
    else {
      if (!class_exists($definition)) {
        throw new \InvalidArgumentException(sprintf('Class "%s" does not exist.', $definition));
      }

      if (is_subclass_of($definition, 'Drupal\Core\DependencyInjection\ContainerInjectionInterface')) {
        $instance = $definition::create($this->container);
      }
      else {
        $instance = new $definition();
      }
    }

    if ($instance instanceof ContainerAwareInterface) {
      $instance->setContainer($this->container);
    }

    return $instance;
  }

}
2
4k4

サービスとして定義しないと、カスタムクラスで依存性注入を使用できません。

質問はここでより詳細に回答されています: カスタムクラスでの依存性注入

0
Dmitry Boychev