Závislosti s proměnným názvem
- medhi
- Generous Backer | 255
Ahoj, používám takový pattern, kdy v presenteru dostanu zvenčí název
třídy a tu si pak načtu jako službu pomocí
$this->context->getByType(...);
a spustím na ní metodu
run()
, tedy nějak takto:
$commandClassName = "App\\ApiModule\\Commands\\" . ucfirst($commandName) . "Command";
if (empty($commandName) || ! class_exists($commandClassName)) {
$this->terminate();
}
$command = $this->context->getByType($commandClassName);
$command->run(...);
Lze toto nějak vyřešit bez použití $this->context
,
které nyní už hází deprecated?
Díky
- Marek Bartoš
- Nette Blogger | 1260
Obecný postup je vytvořit si extension, zaregistrovat si v ní službu a do té služby předat mapu klíčů podle kterých hledáš službu a název služby. Do klíče si dáš ‚type‘ z definice služby, do hodnoty ‚name‘ z definice služby. Služba pak z containeru získá tvůj command pomocí názvu služby z toho commandu.
Používám tenhle pattern na lazy loading kolekcí často, tak jsem si
udělal type-safe helper https://github.com/…cs/README.md#…
Jednoduchá implementace je v ukázce, případně tady: https://github.com/…yManager.php
V extension je pak registrace rozdělená do loadConfiguration(), kde se
registruje „manager“ a do beforeCompile(), kde se do manageru přidává
mapa služeb. Pokud nechceš manager konfigurovat v neonu nebo jiných
extensions, tak ti stačí obojí udělat naráz v beforeCompile() https://github.com/…xtension.php#…
Fajn na tom je, že všechny služby najdeš už při kompilaci a nemusíš do containeru ukládat metadata pro getByType()
Editoval Marek Bartoš (18. 5. 2022 11:07)
- medhi
- Generous Backer | 255
Marek Bartoš napsal(a):
Obecný postup je vytvořit si extension, zaregistrovat si v ní službu a do té služby předat mapu klíčů podle kterých hledáš službu a název služby. Do klíče si dáš ‚type‘ z definice služby, do hodnoty ‚name‘ z definice služby. Služba pak z containeru získá tvůj command pomocí názvu služby z toho commandu.
Používám tenhle pattern na lazy loading kolekcí často, tak jsem si udělal type-safe helper https://github.com/…cs/README.md#…
Jednoduchá implementace je v ukázce, případně tady: https://github.com/…yManager.php
V extension je pak registrace rozdělená do loadConfiguration(), kde se registruje „manager“ a do beforeCompile(), kde se do manageru přidává mapa služeb. Pokud nechceš manager konfigurovat v neonu nebo jiných extensions, tak ti stačí obojí udělat naráz v beforeCompile() https://github.com/…xtension.php#…Fajn na tom je, že všechny služby najdeš už při kompilaci a nemusíš do containeru ukládat metadata pro getByType()
Díky, to už je pro mě dost kanón na vrabce (čti, je to na mě moc složitý).
Zatím po delším zkoumání jsem skončil u předání všech závislostí
přes jednu inject*
metodu, uložení jich do privátních
proměnných a potom je volám jako $this->$className
.
Pokud těch tříd je do 10 kusů, tak to ještě není tak nepřehledný.
- medhi
- Generous Backer | 255
Mimochodem, přesně pro tyhle případy nechápu, proč už není kontejner kdekoli stále k dispozici. Tady se z jednoduchého pochopitelného a čitelného kódu stává něco hodně ošklivého :( Princip a užitečnost DI chápu, ale asi by to nemělo být za každou cenu. Jenom můj hodně laický pohled.
- Marek Bartoš
- Nette Blogger | 1260
Tak můžeš to obejít tak, že si Container injectneš do třídy sám.
Já používám komplikované řešení, protože se celé schová do jedné třídy (+extension, když chceš služby zadrátovat automaticky), nepotřebuje jinak zbytečná data ve vygenerovaném kontejneru, o všech chybách se dozvím už při kompilaci kontejneru, je to snadno přetížitelné v konfigu a lze napsat i propojení s phpstanem a zjistit, zda každá z těch v runtime získávaných služeb existuje.
- medhi
- Generous Backer | 255
Marek Bartoš napsal(a):
Tak můžeš to obejít tak, že si Container injectneš do třídy sám.
Já používám komplikované řešení, protože se celé schová do jedné třídy (+extension, když chceš služby zadrátovat automaticky), nepotřebuje jinak zbytečná data ve vygenerovaném kontejneru, o všech chybách se dozvím už při kompilaci kontejneru, je to snadno přetížitelné v konfigu a lze napsat i propojení s phpstanem a zjistit, zda každá z těch v runtime získávaných služeb existuje.
Snad se jednou dopracuju i tomu, věřím, že to mám spoustu dalších
výhod. Zatím zkusím to injectnutí Containeru. Poradíš jak na to? A je to
velká prasárna? Předpokládám menší než
$this->getContext()
.
Díky
- Marek Bartoš
- Nette Blogger | 1260
Jak píše David a je to úplně totéž co
$this->getContext()
. Jen už si o Container musíš říct
sám, namísto toho aby byla závislost přímo v Nette.