0

I'm building a custom form (extending ConfigFormBase) and using static method File::load($fid). How to use dependency injection to call this method? Thank you!

2 Answers 2

3

In __construct() you can implement like this:

use Drupal\Core\Entity\EntityTypeManagerInterface;

public function __construct(EntityTypeManagerInterface $entity_type_manager) {
    $this->entityTypeManager = $entity_type_manager;
}

and create() method

public static function create(ContainerInterface $container) {
    return new static(
      $container->get('entity_type.manager'),
    );
}

You can use this service to get the file storage:

$file_storage = $this->entityTypeManager()->getStorage('file');

and then load the file:

$file = $file_storage->load($fid);
7
  • I have already checked for that possibility but in vain. entityTypeManager() is not present from ConfigFormBase calss.
    – foopal
    Sep 14, 2018 at 10:23
  • I updated my answer.
    – Tony
    Sep 14, 2018 at 10:33
  • 1
    This is only one half of it - you also need to override the ‘create` method and instantiate an appropriate instance in it. That’s how the dependency gets injected
    – Clive
    Sep 14, 2018 at 10:33
  • I added in my class declaration: class myClassForm extends ConfigFormBase implements ContainerInjectionInterface
    – foopal
    Sep 14, 2018 at 10:45
  • 4
    Yes you need to construct the parent with its required parameters as well, that's just how OOP works. It sounds like you haven't read drupal.org/docs/8/api/services-and-dependency-injection/… yet, it's important that you read an understand that before ploughing ahead with development
    – Clive
    Sep 14, 2018 at 11:29
1

This is my final code implementation as I was having this sort of warning:

Expected \Drupal\file\FileStorageInterface, got object Invocation parameter types are not compatible with declared.

So I updated create method to get the file storage directly:

class MyClassForm extends ConfigFormBase {

  /**
   * File storage for files.
   *
   * @var \Drupal\file\FileStorageInterface
   */
  protected $fileStorage;

  /**
   * SiteSettingsForm constructor.
   *
   * @param \Drupal\file\FileStorageInterface $file_storage
   *   File storage for files.
   */
  public function __construct(EntityTypeManagerInterface $entity_type_manager, ConfigFactoryInterface $config_factory) {
    parent::__construct($config_factory);
    $this->fileStorage = $entity_type_manager->getStorage('file');
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('entity_type.manager'),
      $container->get('config.factory')
    );
  }
}
2
  • 1
    You should use the entity_type.manager service and then in your __construct assign $file_storage with ->getStorage('file') Sep 14, 2018 at 15:25
  • Well the best would be to inject the FileStorage in the first place. Unfortunaley standard D8 does not come up with a Storage ServiecProvider functionality. Because right now no matter you assign the FileStorage in the constructor, in your test you will have to still mock the "getStorage" method no matter what.
    – ssibal
    Sep 17, 2018 at 11:21

Your Answer

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

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