Dependency Injection
Overview
Forge Framework provides a powerful dependency injection system that helps manage class dependencies and promotes loose coupling in your applications. The framework offers multiple ways to inject dependencies, from explicit constructor injection to convenient property injection using annotations.
Container
The Container class is the heart of Forge's dependency injection system. It provides methods for binding and resolving dependencies:
// Binding a concrete implementation to an interface
$container->bind(RouterInterface::class, BasicRouter::class);
// Binding a singleton
$container->singleton(DatabaseInterface::class, MySQLDatabase::class);
// Binding an instance
$container->instance(Config::class, new Config());
Constructor Injection
Constructor injection is the most explicit way to inject dependencies. The container automatically resolves constructor parameters:
class RouterModule extends ModulesInterface
{
private ModuleManifest $manifest;
public function __construct(ModuleManifest $manifest)
{
$this->manifest = $manifest;
}
public function register(Container $container): void
{
$container->instance(RouterInterface::class, new BasicRouter($container));
$container->instance(ModuleManifest::class, $this->manifest);
}
}
Property Injection
Forge supports property injection using the @inject annotation, making dependency injection more convenient in controllers and other classes:
class HomeController
{
/**
* @inject
*/
private ViewEngineInterface $view;
/**
* @inject
*/
private Session $session;
public function index(Request $request): Response
{
return $this->view->render('landing.index', $data, 'base');
}
}
App Helper
The App helper class provides convenient static methods to access commonly used services from the container:
// Get the database service
$db = App::db();
// Get the router service
$router = App::router();
// Get the configuration service
$config = App::config();
// Get the storage service
$storage = App::storage();