The service container is the core of dependency injection in Marwa Framework. It manages class instantiation, dependency resolution, and service binding.
Marwa uses League\Container as its underlying container with automatic dependency injection via reflection.
app() Helper// Get the container itself
$container = app();
// Get a bound service
$cache = app(CacheInterface::class);
$logger = app(LoggerInterface::class);
use Marwa\Framework\Contracts\CacheInterface;
use Psr\Log\LoggerInterface;
class UserRepository
{
public function __construct(
private CacheInterface $cache,
private LoggerInterface $logger
) {}
}
// Auto-resolved via constructor
$repository = app(UserRepository::class);
use Marwa\Framework\Application;
use App\Services\PaymentProcessor;
use App\Contracts\PaymentGatewayInterface;
$app->add(PaymentGatewayInterface::class, PaymentProcessor::class);
// Now inject the interface
$gateway = app(PaymentGatewayInterface::class);
// Same instance returned every time
$app->addShared(MyService::class, new MyService());
// Or via closure
$app->addShared(CacheInterface::class, function () {
return new RedisCache();
});
$service = new MyService();
$app->addShared(MyService::class, $service);
The container automatically resolves dependencies via reflection:
class OrderController
{
public function __construct(
private OrderRepository $orders,
private PaymentGateway $payments,
private LoggerInterface $logger
) {}
}
// All dependencies automatically resolved
$controller = app(OrderController::class);
// Simple resolution
$service = app(MyService::class);
// With arguments
$service = new MyService($arg1, $arg2);
$app->add(MyService::class, $service);
use League\Container\Container;
$container = app()->container();
// Add with factory
$container->add(MyService::class)
->addArgument(Database::class)
->addArgument(LoggerInterface::class);
// Shared (singleton)
$container->addShared(CacheInterface::class, RedisCache::class);
// Inflector for method injection
$container->inflector(MyService::class)
->invokeMethod('setLogger', [LoggerInterface::class]);
// Get configuration value
$dbHost = config('database.host', 'localhost');
// Get config object
$config = app(\Marwa\Framework\Supports\Config::class);
// Get cache instance
$cache = cache();
// Get cached value
$value = cache('key', 'default');
// Set cache
cache()->set('key', $value, 3600);
// Get storage instance
$storage = storage();
// Get specific disk
$storage = storage('local');
// Get database manager
$db = db();
// Get default connection
$conn = $db->connection();
// Get specific connection
$conn = $db->connection('pgsql');
// Set a simple value
$app->set('app.version', '1.0.0');
// Set an instance
$app->add(MySingleton::class, new MySingleton());
if ($app->has(CacheInterface::class)) {
// Cache is bound
}
CoreBindingsBootstrapperapp() calls in constructorsapp() throughout controllers)