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
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);
-
I have already checked for that possibility but in vain. entityTypeManager() is not present from ConfigFormBase calss.– foopalSep 14, 2018 at 10:23
-
-
1This 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– foopalSep 14, 2018 at 10:45
-
4Yes 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
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')
);
}
}
-
1You 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.– ssibalSep 17, 2018 at 11:21