Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spots where dependency injection is impossible because type hinting expects implementations, not interfaces #1361

Closed
qadan opened this issue Nov 21, 2019 · 2 comments

Comments

@qadan
Copy link

qadan commented Nov 21, 2019

This originally cropped up when enabling the webprofiler submodule of the Devel module. webprofiler implements a whole bunch of interfaces to inject, including an EntityManagerWrapper which is put in place of the standard EntityTypeManager. It doesn't extend the EntityTypeManager however, it only implements EntityTypeManagerInterface.

There's a bunch of examples of where this would trip things up in Islandora; I'll just pull the first one:

NodeLinkHeaderSubscriber takes an @entity_type.manager as its first argument, and in the actual implementation inherited from LinkHeaderSubscriber, it's type hinted to use Drupal\Core\Entity\EntityTypeManager.

So, webprofiler tries to inject its EntityManagerWrapper as the @entity_type.manager, but the type hint is looking for an actual EntityTypeManager or subclass thereof, which EntityManagerWrapper is not one of, so it goes boom.

The Drupal docs on dependency injection are disappointingly unclear on what they want you to do here ... the services.yaml definition says to use "the default class that provides the service, or if the service uses a factory class, the interface for the service" ... but they often document the default class instead of the interface, like with @entity_type.manager.

Anyway, that's all just an aside I guess. In practice modules use the interface providing a service to type hint (content_sync and search_api_solr both have examples of this specific service being implemented using the interface instead of the class), and we should follow suit to properly facilitate dependency injection. Even in Drupal\islandora\EventSubscriber\LinkHeaderSubscriber, the @entity_type.manager and @entity_field.manager don't type hint the interface, but then other stuff like @access_manager and @current_user do, so consistency is also a factor here.

Logging this issue specifically to look at auditing the codebase for spots where type hinting is going to reduce or prevent our ability to dependency inject, as this reduces our ability to extend Islandora 8 via contrib modules. EntityTypeManager is one example, but suspect others may exist. Logging the issue also to perhaps make a hard rule for development to use interface type hinting.

@dannylamb
Copy link
Contributor

dannylamb commented Dec 30, 2019

I did a quick audit and it looks like we are injecting the EntityTypeManager, EntityFieldManager, and FileSystem services without using their interfaces. Some vim -> grep -> %s action should take care of this...

@whikloj
Copy link
Member

whikloj commented Jan 29, 2020

Resolved with Islandora/islandora@0d9019b

@whikloj whikloj closed this as completed Jan 29, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants