Pořadí definice extensions
- baraja
- Nette Blogger | 29
Ahoj,
vždycky mě zajímalo, jestli existuje v Nette nějaký způsob, jak můžu jako autor DI extensions ovlivnit, v jakém pořadí se budou jednotlivá rozšíření kompilovat a případně jak zkontrolovat, že se pořadí kompiluje správně.
Podle pozorování to nyní funguje pravděpodobně tak, že se nejprve zkompilují všechny výchozí rozšíření, které definuje samotné jádro Nette a poté se postupně kompilují uživatelská rozšíření v tom pořadí, v jakém jsou v poli po zamergování všech neonů do sebe.
Tento přístup dává vývojáři relativně velkou volnost, ale zároveň autorovi balíčku trochu komplikací.
- Jak například mohu zjistit, že nějaká extension už byla zaregistrována?
- Existuje způsob, jak vytvořit závislost na službě z jiné extensions tak, aby se provedla i když se extensions vyhodnotí ve špatném pořadí?
- Může extensions o sobě říct, že musí být vyhodnocena až po nějaké jiné a případně si pořadí Nette samo v paměti prohodí?
Zejména třetí otázka by přinesla řešení řady složitých situací. Například v extension pro Doctrine definuji řadu obecných služeb, nicméně rád bych v dalších extensions (které jsou na Doctrine závislé) přidal nějaké setup parametry a podobně. Pokud se ovšem extensions zaregistrují ve špatném pořadí, tak aplikace selže.
Uživatel balíků závislosti podle názvů extensions nutně nezná, proto neví, jak moc si může dovolit jejich pořadí prohodit. Správnost totiž pozná pravděpodobně jenom podle vyhozené výjimky po selhané kompilaci.
Budu moc rád za všechny nápady, hodně by to pomohlo.
Díky moc!
- Mistrfilda
- Člen | 76
Ahoj,
Nejsem úplně expert na složité DI extensions :D ale v poslední době jsem na problém s pořadím registrace extension v configu také narazil. Bylo to u nettrine balíčků, kdy jsem prohodil registraci pár služeb, trvalo mi chvilku než jsem to zdebugoval – dopsalo se to pak i do readme projektu zde https://github.com/…cs/README.md#… – to mi přijde jako jedna z cest. Použít jednoduše readme projektu, kde na to uživatele upozornit.
Druhá věc, co mě nepadá, je napsat jednu velkou extension, která by nahradila ty malé. Úplně jsem toto řešení nezkoumal, ale tipuji, že by se tam asi dalo hledat, jestli je nějaký balíček nainstalovaný a na základě toho, určit v jakém pořadí jednotlivé extension zaregistrovat – na toto téma jsem našel toto např. https://forum.nette.org/…lerextension
- Toanir
- Člen | 57
Hoj hoj,
Řeším problematiku modulů skrze extensiony a zatím se mi s vlastními
extensionami daří vyhýbat problémům s pořadím načítání
vyplývajícím z pořadí konfigurace.
Snažím se vždy závislosti a úkony rozložit mezi
loadConfiguration a beforeCompile metody.
V loadConfiguration se postarám o to, aby bylo pro danou
funkcionalitu všechno připraveno a zadefinováno uvnitř ContainerBuilderu.
O samotný poslepování se potom starám
v beforeCompile.
Pokud chápu správně životní cyklus kompilace kontejneru, při beforeCompile by měl ContainerBuilder obsahovat definice ze všech ostatních extension a ty bys měl být schopný si závislost vytáhnout pomocí metody getByType / findByType. Alternativně si můžeš do konfigurace nechat poslat název služby, kterou chceš dekorovat / předat.
Nepomohlo by ti přesunout část konfigurace kompilace do beforeCompile?
- 2bfree
- Člen | 248
Řešil jsem podobná témata.
Nejprve jsem narazil na potřebu si zaregistrovat nějakou „obecnější“ doprovodnou službu, která mohla a nemusela být již zaregistrovaná z jiné extension.
K tomu slouží helper setupServiceAlias
, který nastaví pro
danou extension alias pro případnou již existující službu, aby s tím
šlo dále pracovat, jako by byla vytvořená lokálně. Nebo to vrátí
false
, tedy že služba daného typu ještě neexistuje, pak je
možné (a potřeba) službu registrovat.
Použití viz například zde
Po čase jsem ale narazil na omezení, že je potřeba navěsit službu opravdu v konkrétním pořadí (před / za) jinoujiž registrovanou službu.
K tomu slouží registration helpery processRegisterAfter
a
processRegisterBefore
.
Použití viz například zde
Snad to alepoň takto pomůže
- Felix
- Nette Core | 1245
V nove verzi jsem se zameril na poradi extensions, resp. zjednoduseni, aby to nebylo potreba.
Priklad z https://github.com/…ine-skeleton
extensions:
console: Contributte\Console\DI\ConsoleExtension(%consoleMode%)
nettrine.dbal: Nettrine\DBAL\DI\DbalExtension
nettrine.orm: Nettrine\ORM\DI\OrmExtension
nettrine.dbal:
debug:
panel: %debugMode%
connections:
default:
driver: %postgres.driver%
host: %postgres.host%
port: %postgres.port%
dbname: %postgres.dbname%
user: %postgres.user%
password: %postgres.password%
charset: UTF8
serverVersion: 15.0.0
second:
driver: %mariadb.driver%
host: %mariadb.host%
port: %mariadb.port%
dbname: %mariadb.dbname%
user: %mariadb.user%
password: %mariadb.password%
charset: UTF8
serverVersion: 10.10.0
nettrine.orm:
managers:
default:
connection: default
mapping:
App:
type: attributes
dirs: [%appDir%/Domain/Database]
namespace: App\Domain\Database
second:
connection: second
mapping:
App:
type: attributes
dirs: [%appDir%/Domain/Database]
namespace: App\Domain\Database