Skip to Content

Terrain 4 — Services & DI

🔍 Renfort : Partie 5.

1. Service autowiré ⭐

🕹️ Mission : créez un SlotAvailabilityChecker dépendant de BookingRepository, injectable sans config.

✅ Solution

final class SlotAvailabilityChecker { public function __construct(private BookingRepository $bookings) {} public function isAvailable(int $slotId, int $seats): bool { /* ... */ return true; } }

(Auto-enregistré via App\ dans services.yaml.)

2. Injecter un paramètre ⭐⭐

🕹️ Mission : injectez %kernel.project_dir% dans un service. 🔍 5.2.

✅ Solution

public function __construct(#[Autowire('%kernel.project_dir%')] private string $dir) {}

3. Injecter une variable d’env ⭐⭐

🕹️ Mission : injectez STRIPE_KEY.

✅ Solution

public function __construct(#[Autowire(env: 'STRIPE_KEY')] private string $stripeKey) {}

4. Interface ambiguë ⭐⭐⭐

🕹️ Mission : StorageInterface a deux implémentations ; ciblez S3Storage. 🔍 5.2.

✅ Solution

public function __construct(#[Autowire(service: S3Storage::class)] private StorageInterface $storage) {}

5. Collecter une famille ⭐⭐⭐

🕹️ Mission : collectez tous les NotificationChannelInterface dans un Notifier. 🔍 5.3.

✅ Solution

#[AutoconfigureTag('app.notification_channel')] interface NotificationChannelInterface {} final class Notifier { public function __construct(#[AutowireIterator('app.notification_channel')] private iterable $channels) {} }

6. Priorité de tag ⭐⭐⭐

🕹️ Mission : faites passer SlackChannel en premier dans l’itération.

✅ Solution

#[AsTaggedItem(priority: 10)] final class SlackChannel implements NotificationChannelInterface {}

7. Locator paresseux ⭐⭐⭐⭐

🕹️ Mission : choisissez un exporteur par clé sans instancier les autres. 🔍 5.3.

✅ Solution

public function __construct(#[AutowireLocator('app.exporter')] private ContainerInterface $exporters) {} // $this->exporters->get($format)->export($data);

8. EventSubscriber ⭐⭐⭐

🕹️ Mission : journalisez chaque BookingCreated via un listener. 🔍 5.5.

✅ Solution

#[AsEventListener] final class LogBookingCreated { public function __construct(private LoggerInterface $logger) {} public function __invoke(BookingCreated $e): void { $this->logger->info('Booking créée', ['id' => $e->booking->getId()]); } }

9. Diagnostiquer l’injection ⭐⭐

🕹️ Mission : trouvez quel service sera injecté pour MailerInterface.

✅ Solution

php bin/console debug:autowiring mailer (liste les types injectables et l’implémentation retenue).

10. Service par environnement ⭐⭐⭐⭐

🕹️ Mission : un faux PaymentGateway en dev, Stripe en prod.

✅ Solution

#[When(env: 'dev')] final class FakePaymentGateway implements PaymentGatewayInterface {} #[When(env: 'prod')] final class StripePaymentGateway implements PaymentGatewayInterface {}

Terrain suivant : Doctrine : entités & relations.