Pořadí definovaných služeb?
- uestla
- Backer | 799
Příjemné pozdní ráno.
Občas mám ve své aplikaci problém, když definuji více
služeb dědící od jedné, a sice, že se Nette tváří, že
rodičovská služba neexistuje. Když ji kupříkladu přesunu
na konec (až za potomky), aplikace jede.
Teď jsem bohužel v situaci, kdy se mi nedaří následující
seznam služeb fixnout:
services:
baseFormControlFactory < baseControlFactory:
factory: Components\Factories\BaseFormControlFactory()
aFactory < baseFormControlFactory:
factory: Components\Factories\AFactory()
bFactory < baseControlFactory:
factory: Components\Factories\BFactory()
setup:
- inject( ... )
cFactory < baseFormControlFactory:
factory: Components\Factories\CFactory()
dFactory < baseFormControlFactory:
factory: Components\Factories\DFactory()
eFactory < baseFormControlFactory:
factory: Components\Factories\EFactory()
Ať přesunu definici baseFormControlFactory
kamkoli, vždy
končí chybou
Service ‚baseFormControlFactory‘ not found.
Jen dodám, že baseControlFactory
je definována ještě
výše.
Má někdo tušení, čím to?
PS: Zkoušel jsem updatovat na 2.0.7, chyba zůstává.
PPS: V laděnce jsem rozklikl seznam definovaných služeb, je tam
BaseControlFactory, pak AFactory, ale tam to končí (evidentně kvůli
„neexistující“ rodičovské službě).
- Filip Procházka
- Moderator | 4668
Já třeba dědičnost služeb, od prvního zavedení DIC do Nette, snad ještě nepoužil. Nesmrdí ti to?
- enumag
- Člen | 2118
Ani jsem nevěděl, že Nette nějakou dědičnost služeb umí. K čemu je to vlastně dobré? V dokumentaci o tom není napsané v podstatě nic.
- uestla
- Backer | 799
Řeším tím továrničky (po svém).
Každá továrnička je služba se svými závislostmi
a něco vytvoří – třeba formulář.
No a jelikož mám BaseForm
a od něj dědí další
Form
y, tak by logicky i měly dědit jejich
továrničky od továrničky BaseForm
u (včetně
závislostí).
Akorát to takto hapruje :-(
Co se nových „generovaných“ interface nebo co se
to v tej novej verzi vlastně děje, tak jsem na to
ještě moc nekoukal, každopádně toto je celkem hořák
a formulářů je celkem dost :-(
- Filip Procházka
- Moderator | 4668
@uestla: piš jednoduché služby/továrničky – potom nebudeš potřebovat tyhle pokročilé techniky.
- LeonardoCA
- Člen | 296
Používám to no formuláře a jiné komponenty taky. Než se dostane do stabilní veze inject továrniček a než doladím komponent builder.
@uestla – zkus si vypsat definice služeb konteineru a tam problém najdeš a nebo zakomentovat definice továrniček a postupně odkomentovávat, až přijdeš na to, která definice ti to shodí.
Editoval LeonardoCA (2. 12. 2012 20:40)
- LeonardoCA
- Člen | 296
že ti pomůže to prohazování je podivné, celá „dědičnost“ služeb není nic jiného než slučování polí definic a musí to mít nějaké logické zdůvodnění, ale to bez přesných dat těžko říct
editováno: btw, řekl bych, že dědičnost služeb je špatný pojem. Spíše je to dědičnost nastavení nebo parametrů továrniček, nevím jak to označit správně. Pak by to možná i přestalo některým smrdět
Editoval LeonardoCA (3. 12. 2012 16:08)
- LeonardoCA
- Člen | 296
uestla napsal(a):
Díky za tip. Jak jsem psal výše, Laděnka mi všechny
ostatní služby (coby továrničky) vypíše, kromě právě
té inkriminované.
Pokud by jsi to ještě někdy řešil tak ještě upřesním – vypsáním definic služeb jsem nemyslel to co vypisuje laděnka, ale přímo obsah pole definitions během sestavování containeru.
Asi postupně nejlépe postupně na více místech než to najdeš:
asi nejlépe tady:
https://api.nette.org/…ler.php.html#145
možná už dříve:
https://api.nette.org/…ler.php.html#224
nebo možná i na jiných místech, to záleží na tom kde objevíš
nesrovnalosti
Protože mi to vrtalo hlavou, tak jsem si trochu prošel zdrojáky a obávám se, že když problém vyřešíš pohým přesunutím v config.neon tak ti to funguje tak trochu náhodou a chybu tím obcházíš. Podle mně máš buď některou definici zdvojenou a pak se ti díky tomu sestaví definice při určité kombinaci špatně, ale někdy náhodou docílíš posloupnosti, že nette chybu neodhalí. (a nebo co je méně pravděpodobné se jedná o zákeřný bug nette v tom jak merguje definice a chtělo by to prošetřit).
Pokud by se ti podařilo sestavit nějakou minimální verzi sandboxu, kdy ti to hlásí takovou chybu, tak se na to rád podívám (abych náhodou nenarazil v budoucnu taky)
- uestla
- Backer | 799
Vzdal jsem pokusy o přesouvání pořadí,
myslím, že to souvisí s počtem děděných
služeb.
Jakmile přesáhnu určitý počet, prostě se
to zblázní. Zbylé potřebné služby jsem tedy
zkusil bláhově nadefinovat v bootstrapu:
$container = $configurator->createContainer();
MyConfigurators::configure( $container ); // debug panel, form addons, etc.
$mcf = new MyControlFactory;
$mcf->inject( <dependencies ...> );
$container->addService('myControlFactory', $mcf);
Bohužel při requestu na presenter, který má
metodu inject( MyControlFactory $mcf )
mně
to vynadá, že
No service of type MyControlFactory found. Make sure the type hint in Method MyPresenter::inject() is written correctly and service of this type is registered.
Když si hned za addService()
vyžádám danou
službu, krásně se mi vydumpuje – čili tam je.
Možná, že se presenter vytváří ještě dříve, než
v bootstrapu službu přidám, ale kde?
To je past vedle pasti, py*o.
Jelikož se při autowiringu volá na kontajnéru
getByType()
,
zkusil jsem ještě bláhověji po přidání service do kontajnéru
zavolat
$container->classes[] = 'mycontrolfactory';
doufaje, že ji najde.
Nenašel.
Editoval uestla (4. 12. 2012 13:01)
- uestla
- Backer | 799
HosipLan: Děkuji, v návalu stresu jsem si
toto neuvědomil.
Celou situaci jsem nakonec vyřešil předáním
závislosti továrničky přímo presenteru a jejím
ručním vytvořením a následným předáním oněch
závislostí.
Není to ideální, nicméně mě ta nefunkčnost už
na straně Compiler
u bolí :-(