nette/nette — pull request #650 by VasekPurchart (2012-05-13 19:57:19+00:00)
Title: Presenter - inject dependecies

Ahoj,

závěrem debaty u minulého pull requestu [PresenterDependencies](https://github.com/nette/nette/pull/643) bylo, že vyžadovat předávání závislostí v konstruktoru by bylo zřejmě příliš pracné a hledali jsme tedy alternativu.

Tu @dg nastřelil v podobě injectPrimary, které nahradilo v Presenteru metodu setContext. Tento pull se zabývá rozvinutím a dotažením této myšlenky.

Účelem inject tedy bude předávat veškeré přímé závislosti, které Presenter potřebuje. Vzhledem k tomu, že tato metoda slouží pouze pro inicializaci, tak nejde o klasický setter, který je obecně možné volat vícekrát. Tato skutečnost se v samotné metodě kontroluje (především proto, aby bylo jasné k čemu vlastně slouží a někdo ji nevolal byť neúmyslně vícekrát).

Způsob, jakým se inject metody při vytváření Presenteru v PresenterFactory volají, zaručuje, že když si jakýkoli potomek/předek nadefinuje svoji vlastní inject metodu/metody, tak budou budou nejdříve volány inject metody předků a teprve následně jejich potomků. Jediný čas, kdy objekt tedy bude částečně nekonzistentní je při provádění konstruktoru - pokud zde někdo použije metody presenteru, které závisí na ještě nenastavených závislostech, tak buď může skončit na fatal-erroru nebo by se případně mohl dočkat i nepředvídatelného chování nějaké metody. Ostatně viz rozebrání výhod a nevýhod jednotlivých způsobů u PresenterDependencies a v Davidově článku, který tam odkazoval.

Trochu problém je s tím, že momentálně není žádný pěkný způsob, jak předávat parametry, které nelze autowirovat (skalární/specificky nakonfigurovaná služba). Tohle se tedy do budoucna bude muset ještě dořešit.

Díky tomuto refaktoringu už celý Presenter momentálně pracuje s přímými závislostmi místo práce s Contextem. Ten tam nadále zůstává jednak proto, že ho na několika místech používá Control pro práci se šablonami a také kvůli zpětné nekompatibilitě z pohledu uživatelů (použíávání getContext a getService).

---

Opět jde pouze o první krok v řadě změn, takže co by mělo následovat:
1. Refaktoring Control, tak aby nepotřeboval používat Context, ideálně aby se nepotřeboval dotazovat na služby Presenteru
2. Doplnit deprecated warning do metod jako getContext, getUser, getHttpContext - pokud uživatel tyhle záležitosti potřebuje, měl by si je klasicky vyžádat v konstruktoru - to opět zvýší future-compatibility
3. Zrušit getContext, getService, ostatní metody překlopit na private nebo také zrušit

---

Dále se celkem zdvihla vlna nevole proti injectPrimary, na jménu moc nezáleží, klidně to můžeme nechat, dát injectPresenterDependencies nebo něco úplně jiného, pište návrhy. Vzhledem ke své povaze se to jméno nikde defacto objevovat nebude, takže na něm nesejde.