Pořadí definovaných služeb?

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
uestla
Backer | 799
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

Ř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ší
Formy, tak by logicky i měly dědit jejich
továrničky od továrničky BaseFormu (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 :-(

pekelnik
Člen | 462
+
0
-

Dedicnost sluzeb vubec nepouzivam. Smrdi mi to.

Filip Procházka
Moderator | 4668
+
0
-

@uestla: piš jednoduché služby/továrničky – potom nebudeš potřebovat tyhle pokročilé techniky.

LeonardoCA
Člen | 296
+
0
-

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)

uestla
Backer | 799
+
0
-

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é.

Zakomentovávací trik zkusím, díky.

uestla
Backer | 799
+
0
-

LeonardoCA:
Dals mi naději, která mi dodala sílu
zkoušet to dál. A oplatilo se! Našel jsem inkriminovanou
službu, pěkně ji prohodil s jinou a už to šlape.

Ovšem dědičnost služeb by si zasloužila velkou
ceduli „KŘEHKÉ“

LeonardoCA
Člen | 296
+
0
-

ž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)

uestla
Backer | 799
+
0
-

Škoda jen, že každé další přidání nové
poděděné služby je čirým utrpením :-(

LeonardoCA
Člen | 296
+
0
-

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
+
0
-

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)

Filip Procházka
Moderator | 4668
+
0
-

Protože $classes musí obsahovat název třídy => název služby

pekelnik
Člen | 462
+
0
-

To je past vedle pasti, py*o.

:D

uestla
Backer | 799
+
0
-

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ě Compileru bolí :-(