Installation: Add the package via Composer:
composer require astina/injection-bundle:dev-master
Enable the bundle in app/AppKernel.php:
new Astina\Bundle\InjectionBundle\AstinaInjectionBundle(),
First Use Case:
Inject a service or parameter into a controller using annotations. For example, inject the session service and a parameter acme_foo:
use Astina\Bundle\InjectionBundle\Annotation as Inject;
class DefaultController
{
/**
* @Inject\Service("session")
* @var SessionInterface
*/
private $session;
/**
* @Inject\Parameter("acme_foo")
*/
private $foo;
public function indexAction()
{
$foo = $this->session->get($this->foo);
return ['foo' => $foo];
}
}
Where to Look First:
@Inject\Service and @Inject\Parameter annotations.session is a built-in Symfony service, acme_foo should be defined in config.yml).Service Injection:
Use @Inject\Service("service_id") to inject any service registered in the container. Example:
/**
* @Inject\Service("router")
*/
private $router;
Parameter Injection:
Use @Inject\Parameter("parameter_name") to inject container parameters (defined in config.yml or parameters.yml). Example:
/**
* @Inject\Parameter("app.title")
*/
private $appTitle;
Type Hints (Optional): While the package doesn’t enforce type hints, adding them improves IDE support and readability:
/**
* @Inject\Service("session")
* @var SessionInterface
*/
private $session;
Bulk Injection: Group related injections (e.g., all services/parameters for a feature) in a single controller or base controller class.
Base Controller: Create a base controller with common injections to avoid repetition:
abstract class BaseController
{
/**
* @Inject\Service("twig")
*/
protected $twig;
/**
* @Inject\Parameter("app.locale")
*/
protected $locale;
}
Development Workflow:
symfony/var-dumper for debugging container contents).Testing:
createMock or container overrides.$container->set('session', $this->createMock(SessionInterface::class));
Integration with Other Bundles:
Configuration:
Define parameters in config.yml or parameters.yml:
# config.yml
parameters:
acme_foo: "bar"
Service Overrides: Override services in tests or environments:
# config_test.yml
services:
session:
class: App\Tests\MockSession
Performance: The bundle likely uses a compiler pass to resolve injections at compile time. Avoid overusing it for heavy services (e.g., database connections) in controllers; prefer constructor injection in services instead.
Legacy Code: For controllers without annotations, manually fetch services/parameters via the container:
$this->get('session')->get($this->container->getParameter('acme_foo'));
Missing Services/Parameters:
ServiceNotFoundException or ParameterNotFoundException if the service/parameter doesn’t exist.php bin/console debug:container).Annotation Parsing:
AppKernel::registerBundles() and annotations are correctly formatted.Circular Dependencies:
ServiceA injects ServiceB, which injects ServiceA) may cause issues.Late Initialization:
__construct).initialize() method if using Symfony 2.x).Namespace Conflicts:
@Inject namespace might conflict with other annotation namespaces./**
* @Astina\Bundle\InjectionBundle\Annotation\Service("session")
*/
Check Injections: Dump the container to verify services/parameters exist:
php bin/console debug:container | grep "service_id\|parameter_name"
Compiler Pass Debugging:
If injections fail silently, enable debug mode and check logs for AstinaInjectionBundle errors.
Annotation Processing:
Use a tool like phpDocumentor to validate annotations:
composer require --dev phpdocumentor/phpdocumentor
vendor/bin/phpdoc -d src --parse-tags
IDE Support:
Configure your IDE (e.g., PHPStorm) to recognize @Inject annotations for autocompletion and navigation.
Documentation: Document injected services/parameters in the controller’s PHPDoc to clarify dependencies:
/**
* @Inject\Service("session")
* @var SessionInterface $session The Symfony session service.
*/
Alternatives:
public function __construct(private SessionInterface $session, private string $foo) {}
Extension Points:
config.yml to modify behavior.Performance Note:
Testing:
ContainerAwareInterface or ContainerAwareTrait for testing if injections are problematic:
$controller = new DefaultController();
$controller->setContainer($this->createMock(ContainerInterface::class));
How can I help you explore Laravel packages today?