Podmíněná registrace služby

Polki
Člen | 553
+
0
-

Zdravím komunito.
Dnešní dotaz je na ty, kteří umějí tvořit NetteDI rozšíření.

Představme si, že jsem vytvořil knihovnu, kterou chci zaregistrovat do NetteDI jako službu a chci to udělat pomocí DI extension abych měl možnost si tuto svou knihovnu hezky nahrát do jakéhokoliv projektu a jen pomocí zaregistrování extensiony ji nakonfigurovat a používat.

Ke knihovně jsem udělal i napojení na Latte (nějaký ten Bridge) a taky na Tracy.

Ovšem knihovnu chci používat i na projektech, kde zákazník má trochu jiný tech stack, takže sice používají NetteDI, ale už nepoužívají Latte, nebo nepoužívají Tracy, případně ani jedno.

Otázka je:
Máte někdo nějaké DEMO, kde podmíněně registrujete služby tímto způsobem? Respektive chci říct, pokud je zaregistrováno Latte, zaregistruj i MyLibraryLatteMacro a pak toto makro nainastaluje do Latte?

Marek Bartoš
Nette Blogger | 1146
+
+1
-

V beforeCompile, stačí získat službu se kterou chceš pracovat a kontrolovat že není null

https://github.com/…xtension.php#L251

Polki
Člen | 553
+
0
-

Okay, ale v dokumentaci se u metody beforeCompile píše cituji Metoda se volá ve chvíli, kdy kontejner obsahuje všechny služby přidané jednotlivými rozšířeními v metodách loadConfiguration a taktéž uživatelskými konfiguračními soubory.

Neznamená to, že bych v beforeCompile již neměl přidávat další služby?

Respektive (a je to čistě hypotetická otázka. Nevím, jestli ta situace vůbec může nastat) co když poté vytvořím nějakou další servicu, kterou chci zaregistrovat pouze ve chvíli, kdy je již zaregistrovaná ta moje servica, která je zase závislá na tom latte a zároveň tato další je v jiné separátní extension?

Tam by mohlo nastat, že v první extensioně se sice díky tomu, že latte používám to macro, nebo jiná věc opravdu zaregistruje, ale co když se metoda beforeCompile u té druhé zavolá dříve?

Na příkladu co jsi poslal bych to ukázal tak, že co když bych vytvořil nějakou službu, kterou chci zaregistrovat pouze, pokud je zaregistrovaná Orisai\Localization\Bridge\Latte\TranslationFilters služba? V ten moment jsem závislý na pořadí vykonávání beforeCompile metod ne?

A ještě dotaz:

->addSetup('?->onCompile[] = static function(? $engine) { ?::install($engine->getCompiler()); }', [

Nejde to nějak jinak? Nelíbí se mi, že bych měl psát kód do řetězce. Nevím proč, ale je mi to proti srsti.
Nejspíš se mi to asociuje s funkcí eval, se kterou se musí tak opatrně, že mám z toho vždy obavy :D Nepřijmá addSetup třeba něco jako PhpGenerátor nebo tak?

Editoval Polki (8. 5. 2022 20:18)

Marek Bartoš
Nette Blogger | 1146
+
+1
-

Neměl bys, můžeš. Podstatné je, že cokoli co uděláš v beforeCompile už lze změnit pouze v beforeCompile v extension, která byla registrovaná až po té tvé. Pořadí je loadConfiguration() → neony z bootstrapu → beforeCompile()

Samozřejmě můžeš svoji třídu nepodmíněně registrovat v loadConfiguration() a pokud v beforeCompile() zjistíš, že ti pro ni chybí závislost, tak ji v beforeCompile() zase odebereš. Teď už to tak dělám, když jsem psal toto tak jsem byl línej. Když se budeš držet pravidla, že v loadConfiguration() přidáváš služby a v beforeCompile() je konfiguruješ/odebíráš a cokoli na co nepotřebuješ extension dáváš do neonu, tak bys měl být safe.

Ten kód ve stringu se zredukovat dá. Ten teď řeším takto: https://github.com/…xtension.php#…
Předává se jen název metody co se má zavolat a její parametry.
PhpGenerator použít můžeš též. Ve finále nedělá nic jiného, než že vygeneruje právě takový string.

Editoval Marek Bartoš (8. 5. 2022 20:57)

Polki
Člen | 553
+
0
-

On se tam dá předat klasický Callback? Dokonalý. Díky moc. Hodně mi to pomohlo.