Uzavřel jsem mír se ServiceLocator
Nebudu tady zbytečně do hloubky rozebírat, proč dependency injection skrze konstruktor je obvykle ta nejlepší cesta. Ve zkratce je to nádherně explicitní a lokální (tedy neglobální), nezamoříte si třídu nějakým frameworkem a knihovnou, testovatelnost bomba, no prostě boží. Cokoliv jinýho není tak čistý a přímočarý.
A nebudu ani moc rozebírat, proč Singleton nebo o chlup lepší bratříček ServiceLocator jsou v principu zlosynové. Globální stav, ať už měnný, neměnný nebo všelijak konfigurovatelný, který je kdykoliv přístupný z jakýkoliv části má dost explozivní charakter. A můžeme tomu říkat jakkoliv, ale je to prostě slepičinec. To se nedá přetřít na růžovou a udělat lepší.
Jenže. I ten slepičinec je nejlepší hnojivo pro jahody, pokud ho zbavíte amoniaku.
Vytvořil jsem několik tříd, který potenciálně vytvářely další třídy a který vytvářely další třídy. Herní komponenty (představte si to jako komponentu z Unity), v nich state pattern, ve kterém se potenciálně vytvářejí další komponenty. A podobně. A
-> B
-> C
-> D
-> C
. Flow znělo v pořádku a přirozeně, jen ta problematika byla trochu… problematická. No a tyhle věci měly závislosti. Takže když se vytváří D
, už A
musí umět nějak ty závislosti předat dál.
Samozřejmě může pomoci factory třída. Žel komplexita a čitelnost celýho tohodle řešení jde prostě smutně do hajzlu. Všude najednou tahám závislosti a továrny, konstruktory vypadaj jako přecpaná přestupní stanice, věci bobtnaj.
Je to čistý, to jo. Ale je to taky strašlivě hnusný. A to jen kvůli pitomostem, který jsou vopravdu vždycky součástí aplikace. A bavíme se o malý aplikaci, není to knihovna. Není to framework používanej milionem lidí. K čertu, ten kód pravděpodobně uvidí jen moje budoucí já.
A tak jsem uzavřel mír se ServiceLocator, jen teda pro zmíněný herní komponenty a jejich pohunky. Servisky kolem mají striktně dependency injection skrze konstrutor a Autofac tomu všemu diriguje. Každopádně je to tam. A jahody rostou.