Symfony uses two related container APIs at different stages. PHP service configuration declares which classes become services; the kernel build hook registers compiler passes that transform definitions before the container is compiled.
Last updated: October 16, 2026.
// config/services.php
return function (ContainerConfigurator $container): void {
$container->services()
->defaults()->autowire()->autoconfigure()
->load('App\\', '../src/')
->exclude('../src/{DependencyInjection,Entity,Kernel.php}');
};
// src/Kernel.php, inside Kernel::build()
parent::build($container);
$container->addCompilerPass(new RegisterHandlersPass());The first $container is a ContainerConfigurator. The second is a ContainerBuilder. They share a familiar name but expose different responsibilities.
Load services through the configurator
Symfony’s service container documentation shows namespace loading through the services configurator. The resource path is relative to the configuration file. Exclude directories that contain data objects, generated classes, or classes that should not be instantiated as services.
Autowiring resolves constructor arguments by type. Autoconfiguration adds standard tags based on implemented interfaces and attributes. Use explicit definitions when a class needs scalar arguments, a factory, a special tag, or an alias.
Register the pass during container build
A compiler pass operates on service definitions after configuration has loaded. Symfony’s compiler-pass guide registers it through ContainerBuilder::addCompilerPass(), commonly in Kernel::build() for application code. A reusable bundle can register its own pass in its bundle class.
Use a pass when the container must collect tagged services or rewrite definitions. Do not use it merely to call a service at runtime. Keep the pass deterministic: inspect definitions and tags, validate required configuration, and add clear compile-time errors. After changing service discovery or a pass, clear the application cache and inspect the compiled container with Symfony’s service-debugging commands.
When a class is not discovered, first verify its namespace matches its path and that it was not excluded. When the pass cannot find tagged services, confirm autoconfiguration adds the expected tag or declare it explicitly. Continue with the PHP reference, better PHP application structure, and passing controller data to a view.