DecoratorExtension vs generované továrny

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
Zax
Člen | 370
+
0
-
extensions:
    decorator: Nette\DI\Extensions\DecoratorExtension

decorator:
    ISignalsHandlerAware:
        setup:
            - setSignalsHandler(@signals.signals)

Na službách funguje perfektně, na objektech vyráběných generovanou továrnou (komponenty) nikoliv. Injektování pokud vím jde pokud se na továrně zapne inject, proč tedy nejde tohle? :-)

David Matějka
Moderator | 6445
+
0
-

@DavidGrudl predpokladam, ze je to interface, ktery ta vyrabena trida implementuje

David Grudl
Nette Core | 8227
+
0
-

Místo názvu továrny bys měl uvádět název té vyráběné třídy.

Co je ISignalsHandlerAware?

Zax
Člen | 370
+
0
-

Omlouvám se za nevhodný příklad, je to copy&paste z projektu ve kterým si hraju a experimentuju (mimo jiné v něm nepoužívám Configurator, takže si DI kontejner musím sám složit, včetně uvedení všech extensions) a neměl jsem moc čas se víc rozepsat nebo něco lepšího vymyslet.

Lepší modelová situace:

interface IPaginable {
	function setItemsPerPage($perPage);
}

class SomeControl extends Control implements IPaginable {

	function setItemsPerPage($perPage) {
		// ...
	}

}

interface ISomeControlFactory {
	/** @return SomeControl */
	function create();
}
decorator:
	IPaginable:
		setup:
			- setItemsPerPage(50)

Z tohohle příkladu je doufám jasnější, o co usiluji – chtěl bych globálně ovlivňovat objekty (služby, komponenty) při vyrábění na základě nějakého interfacu.

Pokud ten interface implementuje služba, tak to funguje dobře, pokud ten interface ale implementuje komponenta, vygenerovaná továrna to nezohlední, což mě právě trochu překvapilo, protože generované továrny obecně dost těží ze síly Nettího DI kontejneru (autowiring, inject).

Ale je fakt, že inject se taky definuje na továrně, to mi předtím ani nedošlo.. A teď přemejšlím, jestli to vlastně není blbost – resp. z praktického hlediska na většinu use-casů (mám továrnu na komponenty, chci zapnout inject) to blbost není, ale zrovna v mém případě by dávalo větší smysl, kdyby si Nette projelo interface továrny, zjistilo co se vyrábí za objekt a případně doplnilo další kód v závislosti na ostatních extensions (či dalších vlivů). Pak by bylo možné konfigurovat obecně i objekty tvořené továrnami, definování na továrně to svazuje s tou továrnou a nejde s tím hnout, jedině si psát vlastní implementace a nebo udržovat dvojí konfiguraci (pro služby a pro komponenty/továrnou vyráběné objekty).

Jestli tomu brání nějaká akademická nesprávnost mého uvažování nebo tak něco, tak mám asi holt smůlu a najdu si jinou cestičku, ale z praktického hlediska by se mi něco takového v Nette moc líbilo ;-)

Unlink
Člen | 298
+
+1
-

Aha, tak beriem svoj komentár späť, ono by to malo fungovať presne tak ako očakávaš.
Tvoj ukážkový príklad vygeneruje

final class Container_535cde6f35_ITestComponentFactoryImpl_25_ITestComponentFactory implements ITestComponentFactory
{
	private $container;

	public function __construct(Container_535cde6f35 $container)
	{
		$this->container = $container;
	}

	public function create()
	{
		$service = new TestComponent;
		$service->setItemsPerPage(50);
		return $service;
	}

}

Editoval Unlink (15. 9. 2015 10:42)

Zax
Člen | 370
+
0
-

@Unlink @DavidGrudl
Tak to je naprostá paráda! :-) Díky!

Bohužel jsem ještě neupgradnul phpko, takže nemůžu vyzkoušet, ale aspoň už mám důvod se na to brzy vrhnout :-)

David Grudl
Nette Core | 8227
+
0
-

Updatovat PHP není potřeba, ale mám za to, že to tak fungovalo už předtím komitem.

Zax
Člen | 370
+
0
-

A jo, fakt to funguje, přísahal bych že jsem to zkoušel a nefungovalo mi to. Asi mě zas trollí cache nebo nevím co :-D Tak to je ideál :-)

Unlink
Člen | 298
+
0
-

@DavidGrudl keď to takto funguje pre generované továrničky, nebolo by dobré pridať podporu aj vlastné továrničky?

Povedzme že mám továrničku na formulár, nejako ju zaregistrujem
napr. takto:

services:
    nejakyForm:
		class: Nette\Application\UI\Form
		extend: FormularFactory

A ono by mi to vygenerovalo proxy triedu, ktorá by sa dala upravovať decorátorom podobne ako tie generované?
Či je to úplná hlúposť?

Zax
Člen | 370
+
0
-

@Unlink Pro inspiraci kdyby sis chtěl něco takového ukuchtit sám určitě pomůže ProxyExtension z Venne + jak to funguje ;-)

Unlink
Člen | 298
+
0
-

Tak ono to nieje až taký problém spraviť aj priamo do DIC, trocha som sa s tým hral a upravil aby to fungovalo štýlom ako generované továrničky, len s tým že ak nedostane interface, tak v tej generovanej triede len extendne tu classu a nevygeneruje konštruktor, a vyzeralo že by to tak šlo len rozmýšľam či niečo také ma zmysel, a jedine čo ma napadlo je formulárom globálne nastaviť translator ale to sa dá aj inak, tak neviem či to nieje sprostosť :)

V nette bola kedysi sekcia factories, ktorá bola zrušená, ale vtedy som nette ešte nepoužíval, tak neviem ako to fungovalo.

@Zax diky za odkaz