AutoDI: registrace služeb pohodlně
Poslední dobou stále častěji aplikuji DDD s prvky CQRS v projektech, na kterých pracuji. Ve chvíli, kdy aplikace roste, nám úměrně roste i počet tříd, které potřebujeme registrovat v DI kontejneru. Jak si zjednodušit práci při jejich registraci?
Jednoduchý config.neon
pro Nette aplikaci může vypadat například takto:
services:
- class: Model\User\Handlers\RegisterUserHandler
tags: [commandBus.handler]
- class: Model\User\Handlers\ResetPasswordHandler
tags: [commandBus.handler]
- class: Model\Post\Handlers\PublishPostHandler
tags: [commandBus.handler]
# ... další handlery ...
- Model\User\Repositories\UserRepository
- Model\Post\Repositories\PostRepository
# ... další repozitáře ...
Konfigurace takového kontejneru rychle bobtná a může nabývat stovek až tisíců řádků. Typicky navíc můžeme tyto třídy rozdělit do skupin s podobnou funkcí a namespacem (command handlery, query handlery, repozitáře atd.).
Nešlo by to lépe?
Vlastní CompilerExtension
Jedním z řešení je napsat vlastní CompilerExtension, ale tím přijdeme o přehlednost, kterou nám dává deklarativní zápis v konfiguračním souboru.
AutoDI
Pro úsporný zápis lze použít rozšíření fmasa/auto-di, které jsem pro tento účel připravil.
Původní zápis výše tak lze přepsat na:
extensions:
autoDI: Fmasa\AutoDI\DI\AutoDIExtension
autoDI:
services:
- class: Model\{User,Post}\Handlers\*
tags: [commandBus.handler]
- class: Model\{User,Post}\Repositories\*
Pokud některé třídy vyhovující výrazu nechceme registrovat, můžeme použít exclude
:
- class: Model\User\Repositories\**
exclude: Model\User\Repositories\Excluded\**
Tento zápis nám umožní na pár řádcích registrovat klidně stovky služeb s možností stejné konfigurace jako běžně registrované služby. Služby jsou prohledávány pouze při sestavování kontejneru a dále už kontejner nijak nezpomalují.
Podrobnější návod pro použití včetně složitějších konstrukcí lze najít v anglické dokumentaci k rozšíření.
Jak řešíte velké množství registrovaných služeb vy? Rád si přečtu vaše zkušenosti v komentářích.