Контейнер сервісів Laravel є основою складного управління залежностями, що дозволяє розробникам створювати гнучкі та тестовані додатки за допомогою потужних патернів інверсії контролю. Ця система забезпечує безперешкодне розв'язування класів та впровадження залежностей у складних архітектурах додатків.
Зв'язки між інтерфейсом та реалізацією встановлюють базові відносини контейнера:
use App\Contracts\EventPusher;
use App\Services\RedisEventPusher;
$this->app->bind(EventPusher::class, RedisEventPusher::class);
Розв'язання контейнера здійснюється кількома способами: від автоматичного впровадження до явного розв'язання:
$eventPusher = app(EventPusher::class);
$eventPusher = $this->app->make(EventPusher::class);
public function __construct(EventPusher $pusher)
{
$this->pusher = $pusher;
}
Патерни синглтон забезпечують уніфіковане управління екземплярами протягом життєвого циклу додатка:
$this->app->singleton(EventPusher::class, RedisEventPusher::class);
Створення комплексної системи сповіщень демонструє розширені можливості контейнера в різних конфігураціях сервісів:
interface NotificationService
{
public function send($message, $recipient);
}
class EmailNotificationService implements NotificationService
{
public function send($message, $recipient) { /* Реалізація */ }
}
class SlackNotificationService implements NotificationService
{
public function send($message, $recipient) { /* Реалізація */ }
}
class AppServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->when(AdminController::class)
->needs(NotificationService::class)
->give(EmailNotificationService::class);
$this->app->when(DeveloperController::class)
->needs(NotificationService::class)
->give(SlackNotificationService::class);
$this->app->when(EmailNotificationService::class)
->needs('$apiKey')
->giveConfig('mail.api_key');
$this->app->bind(CpuReport::class, function () {
return new CpuReport();
});
$this->app->bind(MemoryReport::class, function () {
return new MemoryReport();
});
$this->app->tag([CpuReport::class, MemoryReport::class], 'reports');
}
}
class SystemMonitor
{
public function __construct(iterable $reports)
{
$this->reports = $reports;
}
}
$this->app->when(SystemMonitor::class)
->needs('$reports')
->giveTagged('reports');
Архітектура контейнера підтримує патерни розширення для декорації сервісів, контекстне зв'язування для специфічних для середовища реалізацій та впровадження примітивних значень для управління конфігурацією. Ці можливості дозволяють дизайнерам створювати складні архітектури додатків, зберігаючи чистий розподіл відповідальностей і високий рівень тестованості