Dřív a nyní. Aneb $this->context

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

Když se do nette dostalo $this->context, tak tu „tvrdé nette jádro“ (Hosiplan, Honza Tvrdík ..) jásali.
Nyní se však hodně v odpovědích objevuj $this->context se vyhni (příklad).

Byl by někdo tak hodný a popsal, proč takový obrat?
Děkuji

Editoval martinit (2. 10. 2012 19:16)

jansfabik
Člen | 193
+
0
-

Docela dobře je to popsané tady: https://pla.nette.org/…ect-autowire

A důvod, proč je špatné používání $this->context (service locatoru) je tady: https://www.youtube.com/watch?…

edit: Myslím, že na tyto informace by měl být aspoň nějaký odkaz v dokumentaci. Docela to tam chybí.

Editoval jansfabik (2. 10. 2012 19:26)

Ot@s
Backer | 476
+
0
-

$this->context je tzv. service locator (viz. téma návrhové vzory) a v současné době se zdá přežitý. Proč? Protože to je to „globální“ objekt, který obsahuje guláš různých jiných objektů/služeb. Na první, ani druhý pohled nevidíš, co v něm je, bylo a hlavně do budoucna bude. Ve velké většině případů také nevyužiješ ani 1/4 toho, co service locator nabízí/obsahuje – proč tedy mít všechno v paměti a zdržovat se inicializací nepotřebných objektů/služeb. Vývoj se začíná ubírat cestou dekompozice, single responsibility principle, atd… Výborné články o této tématice najdeš přímo od Davida na phpfashion.com.

Edit: Nechci mluvit za ostatní, ale obecně platí, že každý si projde určitým vývojem a poznáním. Podívej se sám na sebe, kde jsi byl před rokem a kde jsi teď.

Editoval Ot@s (2. 10. 2012 19:47)

Marek Šneberger
Člen | 130
+
0
-

Jednoduše řečeno v $this->context (service locatoru) jsou všechny závislosti. Sice se volají, až když je potřebuješ, ale není to ono. Místo toho použiješ Inject* metody a předáš si sám všechny závislosti, které potřebuješ. Jak je napsáno v dokumentaci. Pokud jsi v ArticlePresenteru, s největší pravděpodobností tam budeš potřebovat nějaký ArticleModel. Tak si ho tam pomocí

injectArticles(ArticleModel $articles)
{
$this->articles = $articles
}

přidáš. Potom k modelu nebudeš přistupovat jako $this->context->articles->getArticle… ale jenom $this->articles->getArticle..

jtousek
Člen | 951
+
0
-

Inject v Nette naprosto nijak neřeší lazy vytváření služeb až když jsou opravdu potřeba – vše se vytváří v době vytvoření objektu, který dané služby může potřebovat. Dokud toto nebude vyřešené, což by pomocí tohoto přístupu šlo poměrně jednoduše, zůstávám u $this->context.

Felix
Nette Core | 1190
+
0
-

A co takove tavarnicky nebo sluzby, tam inject* nefunguje, funguje jen u presenteru. Neda se s tim neco delat?

vvoody
Člen | 910
+
0
-

Master uz umoznuje inject* nad sluzbami. Snad coskoro aj v stable.

Filip Procházka
Moderator | 4668
+
0
-

Továrničky je doporučováno řešit takto, ale v budoucnu snad bude generování „vstříknutelných“ továrniček – něco jako tohle, ale asi 10× lepší :)

MartinitCZ
Člen | 580
+
0
-

@**Marek Šneberger:** Ale v tom případě díky injectování ubývají řádky v config.neon?!
Dřív jsem si v config.neon zapsal daný model a pak se k němu dostal přes $this->context->article.
Nyní ho injectnu a tim pádem toto nastavení v config.neon není třeba.

vvoody
Člen | 910
+
0
-

martinit sluzba musi byt minimalne zadefinovana jej nazvom a triedou. Ale ked sa tak zamyslim, vzdy ma stvalo to, ze ked som si vytvoril model a injectol ho do inej sluzby, tak mi vybehla ladenka ze dana sluzba v configu neexistuje lebo som ju tam zabudol napisat.

Myslite ze by sa mohol DIC pokusit v spolupraci s RL o vytvorenie objektu ktory nieje zadefinovany v configu?

22
Člen | 1478
+
0
-

aneb zpět k magii?

Marek Šneberger
Člen | 130
+
0
-

martinit napsal(a):

@**Marek Šneberger:** Ale v tom případě díky injectování ubývají řádky v config.neon?!

@**martinit:** Přesně jak píše @**vvoody**. Inject metody stále pracují se službami. Pokud v configu danou službu nevytvoříš, vyskočí na tebe laděnka s hláškou:

Nette\DI\ServiceCreationException

No service of type MujModel found. Make sure the type hint in Method MujPresenter::injectMujModel() is written correctly and service of this type is registered.
vvoody
Člen | 910
+
0
-

22 samotne autowire (ci uz construct alebo inject*) nieje magia?

edit: ale chapem ze by to uz bola velka prasarna :D Co tak, ze by sa zadefinoval namespace pod ktorym by sa nenajdene sluzby hladali?

Editoval vvoody (3. 10. 2012 14:11)

MartinitCZ
Člen | 580
+
0
-

@**Marek Šneberger:** Aha, to jsem nevěděl. V tom případě injectování práci přidává (musim napsat třídu navíc – inject<name>(…)), místo toho, aby jí usnadnovalo.

Marek Šneberger
Člen | 130
+
0
-

@**martinit** Je pravda, že je to o trochu víc psaní, ale na druhou stranu máš přehled, co a kam se předává za závislosti. Máš nad tím plnou moc :-)

Kdežto v $this->context máš sice přístupné uplně všechno, ale je to zbytečný, když to nepotřebuješ. Až to budeš potřebovat, přidáš si inject() metodu.

vvoody
Člen | 910
+
0
-

@martinit: Cital si tie Davidove clanky/prednasky?

MartinitCZ
Člen | 580
+
0
-

@**Marek Šneberger:** Na tom rozhodně něco je. V podstatě to je podobné stím, že se Nette nyní dělí na samostatné kousky. Nač používat celé Nette, když potřebuji jen Latte.

@**vvoody:** Dnes to mám v plánu. Doufám, že mi to lecos vysvětlí. Ikdyž hodně mi pomohl tento topic.