Problem/Motivation
Modules often implement hooks of other modules they don't depend on as optional integrations. That works basically out of the box with legacy hooks and also new OOP hooks. But they are still registered and their class added to the container when we know they will never be called. For example, user module implements views hooks.
This becomes a bit more complicated if your hook also requires an injected dependency of that module. Because the class is added as a service, it will be invoked and you need to make that dependency optional even though that class and hook actually requires it. And we'll run into that more often when improving Hooks to do proper DI.
And, unlike in old version where hooks were only discovered and cached when invoked, now we add them all to the container.
If you provide a plugin for a given plugin type owned by another module that isn't installed this works as it's never discovered.
Steps to reproduce
Proposed resolution
We can't figure this out automatically, we don't have enough knowledge about hooks and who owns them.
My idea was to make it explicit with a new attribute:
#[Hook('config_translation_info_alter')]
#[HookBy(module: 'config_translation')
public function configTranslationInfoAlter(array &$info): void {
We can check for that, and if config_translation isn't in the container, we skip it. And if a service class has no hooks, we also don't add it to the container.
It might also automatically work if the hook class is defined by that module, like this:
#[ConfigTranslationInfoAlter('config_translation_info_alter')]
public function configTranslationInfoAlter(array &$info): void {
If we can't resolve ConfigTranslationInfoAlter as an attribute class. But I'm not sure yet if we're really going to add hook classes for every hook.
Remaining tasks
User interface changes
Introduced terminology
API changes
Data model changes
Release notes snippet