Drupal: Handling Module Dependencies with Service Tags
When working with Drupal, you’ll often encounter situations where one module depends on another. This dependency ensures that the dependent module can only function if the required module is enabled. However, when it’s time to uninstall or remove a module, these dependencies can cause issues.
For example, imagine you created a custom module (my_module
) that depends on another module (other_module
). If you try to uninstall other_module
without removing the dependency, Drupal won’t let you proceed. Instead of manually editing .info.yml
files or risking accidental breakage, we can leverage service tags to handle dependencies in a cleaner way.
Common Problem
If you attempt to uninstall a module with existing dependencies, you’ll see an error like:
The following modules cannot be uninstalled because they are required by other modules: other_module
This happens because my_module.info.yml
explicitly declares:
dependencies:
- other_module
To safely uninstall without hacking .info.yml
, we can dynamically alter dependencies using a service subscriber.
Solution: Using Service Tags
Drupal allows us to alter a module’s dependency behavior at runtime by subscribing to specific services. For module uninstallation, the service we want is:
module_handler
(to alter module dependencies).
By defining a custom service tagged as event_subscriber
, we can intercept uninstall events and dynamically remove the dependency.
Step 1: Create a Service Subscriber
Inside your custom module (my_module
), add a service file:
my_module.services.yml
services:
my_module.dependency_alter:
class: Drupal\my_module\EventSubscriber\DependencyAlterSubscriber
tags:
- { name: event_subscriber }
Step 2: Implement the Subscriber
Create the class:
src/EventSubscriber/DependencyAlterSubscriber.php
<?php
namespace Drupal\my_module\EventSubscriber;
use Drupal\Core\Extension\ModuleUninstallValidatorInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
* Alters module uninstall validation to remove custom dependencies.
*/
class DependencyAlterSubscriber implements EventSubscriberInterface, ModuleUninstallValidatorInterface {
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents() {
// Subscribe to module uninstall validation.
return [];
}
/**
* {@inheritdoc}
*/
public function validate($module) {
$reasons = [];
// Skip dependency validation for 'other_module'.
if ($module === 'other_module') {
// Do nothing, allow uninstall.
}
return $reasons;
}
}
Step 3: Register as a Validator
Tell Drupal that this class implements uninstall validation by tagging it:
my_module.services.yml
services:
my_module.dependency_alter:
class: Drupal\my_module\EventSubscriber\DependencyAlterSubscriber
tags:
- { name: module_uninstall_validator }
Step 4: Clear Cache & Test
Run:
drush cr
2. Try uninstalling the dependent module:
drush pmu other_module
3. It should uninstall successfully, even though my_module
was depending on it earlier.
Why Use This Approach?
No hacking
.info.yml
files – Keeps module metadata clean.Dynamic dependency handling – You can control uninstall behavior at runtime.
Safe and Drupal-friendly – Uses service tags, aligns with Drupal best practices.
Dependencies are important for module stability, but when it comes to uninstallation, being able to bypass or alter them safely is critical. By using service tags with uninstall validators, you can remove custom module dependencies dynamically, ensuring a smooth and controlled uninstall process without risking core integrity.