Руководство

Сервисы и провайдеры

Регистрация сервисов, binding интерфейсов и явная композиция приложения.

Регистрируйте сервисы в AppServiceProvider

Композиция приложения относится к App\Providers\AppServiceProvider. Для общих сервисов используйте singleton(), для сервисов, создаваемых заново, — set().

example.php
<?php

declare(strict_types=1);

namespace App\Providers;

use App\Services\ArticleRepository;
use Lemonade\Framework\Container\ContainerInterface;
use Lemonade\Framework\Core\ServiceProviderInterface;

final class AppServiceProvider implements ServiceProviderInterface
{
    public function register(ContainerInterface $container): void
    {
        $container->singleton(ArticleRepository::class, ArticleRepository::class);
    }
}

Передавайте зависимости через конструктор

Контроллеры и сервисы должны объявлять зависимости в конструкторе. Так dependency graph остаётся читаемым, а код легче тестировать.

example.php
<?php

declare(strict_types=1);

namespace App\Controllers;

use App\Services\ArticleRepository;
use Lemonade\Framework\Core\AbstractController;
use Psr\Http\Message\ResponseInterface;

final class ArticleController extends AbstractController
{
    public function __construct(
        private readonly ArticleRepository $articles,
    ) {}

    public function detail(int $id): ResponseInterface
    {
        return $this->json($this->articles->find($id));
    }
}

Интерфейсы и типизированная конфигурация

Интерфейсам нужен явный binding. YAML-конфигурацию в runtime используйте через типизированные config-объекты, а не через разбросанные вызовы getenv().

example.php
<?php

declare(strict_types=1);

namespace App\Providers;

use App\Services\NewsletterSender;
use App\Services\NewsletterSenderInterface;
use Lemonade\Framework\Container\ContainerInterface;
use Lemonade\Framework\Core\ServiceProviderInterface;

final class AppServiceProvider implements ServiceProviderInterface
{
    public function register(ContainerInterface $container): void
    {
        $container->singleton(NewsletterSenderInterface::class, NewsletterSender::class);
    }
}