Service container

Bind

The service container builds objects and wires their dependencies automatically. A bind call teaches it how to create a class that needs manual setup.

The closure runs on every resolve, so each call site receives a fresh instance.

app()->bind(ReportBuilder::class, function () { return new ReportBuilder("html"); });

Singletons

A singleton binding runs the closure only once and reuses the same instance afterwards. Shared clients such as cache or mail connections belong here.

One shared instance also means one shared state, so keep singletons stateless whenever possible.

app()->singleton(CacheClient::class, function () { return new CacheClient("127.0.0.1"); });

Resolve

Resolve a binding anywhere with the app helper and the class name. The container runs the matching closure and returns the ready object.

Manual resolving is handy in scripts and tests, while controllers usually prefer injection from the next section.

$builder = app(ReportBuilder::class); $html = $builder->render();

Inject in controllers

Controllers rarely call the container directly. They declare dependencies in the constructor, and the container fills them in on every request.

Constructor promotion keeps the declaration to one line per dependency with no extra property setup.

class ReportController extends Controller { public function __construct(private ReportBuilder $builder) { } public function show(): string { return $this->builder->render(); } }

Next: Config and env

Article author: Arthur Isaev

Banner image