Skip to content

Instantly share code, notes, and snippets.

@fesor
Created August 18, 2016 09:32
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fesor/4ea1896ee05063abfaa8d53154e6507e to your computer and use it in GitHub Desktop.
Save fesor/4ea1896ee05063abfaa8d53154e6507e to your computer and use it in GitHub Desktop.
Symfony: Service auto registration
<?php
namespace App\DependencyInjection;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\Finder\Finder;
class AppExtension extends Extension
{
public function load(array $configs, ContainerBuilder $container)
{
$this->registerServicesIn([
__DIR__ . '/../Http/Transformer'
]);
}
private function registerServicesIn(array $paths)
{
$files = $this->collectServiceDefinitions($paths);
$unregisteredClasses = $this->getUnregisteredClasses($container);
$services = array_intersect_key($unregisteredClasses, array_flip($files));
$this->registerServices($services, $container);
}
private function registerServices(array $services, ContainerBuilder $container)
{
foreach ($services as $className) {
if ($container->has($className)) {
continue;
}
$container
->register($className, $className)
->setAutowired(true);
}
}
private function collectServiceDefinitions(array $paths)
{
$finder = new Finder();
$finder->files()->in($paths)->files()->name('*.php');
$files = [];
foreach ($finder as $file) {
$file = realpath($file);
require_once $file;
$files[] = $file;
}
return $files;
}
/**
* @param ContainerBuilder $container
* @return \ReflectionClass[]
*/
private function getUnregisteredClasses(ContainerBuilder $container)
{
$definitions = $container->getDefinitions();
$registeredClasses = [];
foreach ($definitions as $id => $definition) {
$registeredClasses[] = $definition->getClass();
}
$declaredClasses = get_declared_classes();
$unregisteredClasses = array_diff($declaredClasses, $registeredClasses);
$keys = array_map(function ($className) {
return (new \ReflectionClass($className))->getFileName();
}, $unregisteredClasses);
return array_combine($keys, $unregisteredClasses);
}
}
@fesor
Copy link
Author

fesor commented Aug 18, 2016

TODO:

  • Register all classes defined by given paths as services + autowring
  • Skip if there is any services with given class name of resolved classes
  • Skip Exceptions?
  • Configurable list of excluded paths.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment