Skip to content

Instantly share code, notes, and snippets.

Created December 4, 2012 18:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/4207252 to your computer and use it in GitHub Desktop.
Save anonymous/4207252 to your computer and use it in GitHub Desktop.

Ondra Mirtes: Ahoj, co je za problém s DI v controllerech? :)

VeN: Ahoj, no, je to namáhavé :) Vzhledem k tomu, že nedokážu psát controllery tak, že dělají pouze jednu věc - často pracují nad jednou entitou, ale práce je to různorodá - takže se v controllerech hromadí servisní objekty. No a pokud bych chtěl striktně dodržovat konstruktorovou DI, začínají mi vznikat megatřídy, ve kterých nakonec požaduji něco jako "lazyDI" :) přesně v tom smyslu, jak o ní tehdy psal David Grudl. Vzhledem k tomu všemu mi přijde lepší používat service container přímo. V Symfony se v controllerech servisní instance získá voláním na servisní kontajner "$this->get('article_facade')". Nebudu totiž na controllery psát unit testy, dokonce na ně nebudu ani psát integrační testy. Budu rád, když budu mít controllery pokryté webtesty, které na controllery jdou přes prohlížeč.

Ondra Mirtes: My tam máme DI - v listech hierarchie controllerů normálně přes konstruktor, v předcích přes setter (kvůli tomu zaplevelování konstruktoru, o čemž psal DG). Líbí se mi to víc, protože si tu servisu uložíš někam do $this a nad tu property si napíšeš anotaci -> napovídá to. Navíc to přenáší spoustu chyb do fáze kompilace kontejneru, takže zjistím hodně brzo, když si žádám nějakou neexistující servisu.

VeN: Jj, taky jsem myslel listy hierarchie. V předcích spokojeně používám setter DI. V takovém případě se ale musíš hodně hlídat, aby jsi v controlleru neumožnil dělat moc věcí, protože čím víc akcí, tím víc servis a často to je tak, že nějaká servisa je v controlleru jenom kvůli jedné akci, což zapříčiní, že se ti inicializuje vždy, když controller použiješ. A pokud přistoupíme na to, že se taková index akce zobrazuje např. z 90 % a akce XYZ, která pro svou práci potřebuje určitou servisu, pouze v 10 %, tak jsme v devíti případech z desíti inicializovali něco, co se vůbec nikdy nepoužije. A v controllerech, které mají třeba 10 akcí (to není IMHO zase tak prasácký číslo :)) se můžeš dostat do situace, kdy každá akce používá pod 50 % inicializovaných servis a zbytek tam je jenom pro parádu.

Ondra Mirtes: Deset už je docela dost :) Já v tomhle nevidím zas takovej problém - pokud v konstruktorech jen přiřazuješ předaný parametry, tak IMHO jejich vytvoření tolik nestojí.

VeN: To je pravda, vytvoření další reference nemusí být tak náročný. Nicméně stále tu je otázka, proč to vlastně dělat? Vždycky jsem si říkal, že hlavní důvod je, abych mohl controller jednoduše kdekoliv postavit (např. právě v testech). Jenže ono se ukazuje, že psaní takových (unit a integračních na controllerech) testů je tak mimo místu. IMHO tě na úrovni testování controllerů zajímá hlavně to, jaký produkují obsah. Proto si myslím, že jediné testy, které má cenu pro controllery psát, jsou web testy. Takže suma sumárum, vyměním čistotu za pohodlnost. Ono se totiž nakonec to volání service containeru ($this->get('myService')) nečte tak strašně, jak by to na první pohled mohlo vypadat. Je to standard, od kterého by každý měl vědět, co může čekat.

Ondra Mirtes: My na controllery taky nikdy nepíšem testy, ale má to ty výhody, co jsem psal - IDE ti napovídá a o chybě ("nonexistent service") se dozvíš hned, ne, až se tam doklikáš :)

PS: Bavili jsme se čistě o (konstruktorové) DI v controllerech (v listových - těch, co nemají potomka), jiná DI nebyla tématem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment