Leitfaden
Services & Provider
Serviceregistrierung, Interface-Bindings und explizite Zusammensetzung der Anwendung.
Services im AppServiceProvider registrieren
Die Zusammensetzung der Anwendung gehört in App\Providers\AppServiceProvider. Verwende singleton() für gemeinsam genutzte Services und set() für Services, die bei jeder Auflösung neu entstehen sollen.
<?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);
}
}Abhängigkeiten über den Konstruktor übergeben
Controller und Services sollten ihre Abhängigkeiten im Konstruktor deklarieren. So bleibt der Dependency Graph lesbar und der Code leichter testbar.
<?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));
}
}Interfaces und typisierte Konfiguration
Interfaces brauchen ein explizites Binding. Verwende YAML-Konfiguration zur Laufzeit über typisierte Config-Objekte statt über verstreute getenv()-Aufrufe.
<?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);
}
}