Ответ
В Laravel Dependency Injection (внедрение зависимостей) реализовано через мощный Service Container. Контейнер автоматически разрешает и внедряет зависимости в классы, что способствует слабой связанности и лёгкому тестированию.
Автоматическое разрешение (Automatic Resolution) Контейнер анализирует типы параметров в конструкторе класса и рекурсивно создаёт все необходимые экземпляры.
// Сервис с зависимостью
class PaymentProcessor {
public function __construct(private LoggerInterface $logger) {}
public function process(Payment $payment) {
$this->logger->info('Processing payment: ' . $payment->id);
// ... логика оплаты
}
}
// В контроллере Laravel автоматически внедрит LoggerInterface
class CheckoutController extends Controller
{
public function pay(Request $request, PaymentProcessor $processor)
{
// $processor уже создан с переданным логгером
$processor->process($payment);
}
}
Явная привязка (Explicit Binding) Вы можете указать контейнеру, какую конкретную реализацию использовать для интерфейса. Это делается в сервис-провайдере.
// AppProvidersAppServiceProvider.php
public function register(): void
{
$this->app->bind(
AppContractsPaymentGateway::class,
AppServicesStripeGateway::class // Конкретная реализация
);
// Синглтон: один экземпляр на всё приложение
$this->app->singleton(
AppServicesGeoLocation::class,
function ($app) {
return new GeoLocation($app->make('config')->get('services.geo.key'));
}
);
}
Внедрение в методы (Method Injection) Laravel также поддерживает внедрение зависимостей не только в конструктор, но и в методы контроллеров, middleware, job'ов и т.д.
// Внедрение конкретного Request и кастомного сервиса в метод
public function store(
AppHttpRequestsCreatePostRequest $request,
AppServicesSlugGenerator $slugGenerator
) {
$post = new Post([
'title' => $request->title,
'slug' => $slugGenerator->fromString($request->title)
]);
$post->save();
}
Почему это важно: Такой подход делает код модульным и легко тестируемым. В тестах вы можете легко подменить реальную зависимость (например, подключение к БД) на mock-объект.