draw/dependency-injection
Add-ons for Symfony DependencyInjection to simplify integrating subcomponents into a main bundle. Provides Integration classes and traits to auto-register integrations, load enabled configuration, and prepend container configuration when components are installed.
Installation:
composer require draw/dependency-injection
Add the package to your composer.json dependencies.
First Use Case:
IntegrationTrait in your bundle’s DependencyInjection extension to integrate subcomponents.DrawFrameworkExtraBundle) by integrating smaller components (e.g., MyComponent, MyOtherComponent).Key Files to Review:
IntegrationTrait (for bundle integration logic).ExtendableExtensionTrait (for extending Symfony’s ContainerBuilder).MyComponentIntegration).Define Component Integrations:
DependencyInjection extension, list subcomponent integrations in provideExtensionClasses().protected function provideExtensionClasses(): array {
return [
MyComponentIntegration::class,
MyOtherComponentIntegration::class,
];
}
Automatic Registration:
registerDefaultIntegrations() in the bundle’s constructor to auto-load integrations.Configuration Handling:
loadIntegrations() to process subcomponent configs only if enabled: true.example_my_bundle:
my_component:
enabled: true
# Component-specific config
Service Prepending:
prependIntegrations() to modify the container before your bundle’s services are loaded.public function prepend(ContainerBuilder $container): void {
$this->prependIntegrations($container, 'example_my_bundle');
}
AuthBundle, CacheBundle).enabled: false) to avoid conflicts or reduce overhead.getConfiguration().Circular Dependencies:
prependIntegrations() order matches dependency resolution.provideExtensionClasses().Missing Integration Classes:
if (!class_exists(MyComponentIntegration::class)) {
throw new \RuntimeException('Integration class missing!');
}
Configuration Overrides:
parent::load() carefully to avoid overwrites.Namespace Collisions:
Example\Component\Auth\DependencyInjection\AuthIntegration).var_dump($this->integrations); // Inspect registered integrations in `load()`.
ContainerBuilder logs service modifications. Use:
$container->setDebug(true);
Custom Integration Logic:
loadIntegrations() to add pre/post-processing (e.g., validation).protected function loadIntegrations(array $configs, ContainerBuilder $container): array {
$config = parent::loadIntegrations($configs, $container);
// Custom logic here
return $config;
}
Dynamic Component Discovery:
Composer\Autoload\ClassLoader to auto-discover integrations in provideExtensionClasses():$loader = new \Composer\Autoload\ClassLoader();
$loader->addPsr4('Example\Component\\', __DIR__.'/../../../vendor');
$integrationClasses = $loader->findFiles('*Integration');
Environment-Specific Configs:
if ($_ENV['APP_ENV'] === 'prod') {
$this->integrations[] = new ProdOptimizationIntegration();
}
How can I help you explore Laravel packages today?