nette/nette — pull request #696 by HosipLan (2012-07-04 16:42:31+00:00)
Title: Proof of concept: Generics

Někteří z nás používají například Doctrine 2 ORM. Doctrine má EntityManager a ten poskytuje pomocí metody $em->getRepository($entity) přístup k repozitářům jednotlivých entit.

Pokud bych chtěl mít repozitáře v DIC, tak není problém, prostě pro každou entitu registruju repozitář

services:
usersRepository:
class: Doctrine\ORM\EntityRepository
factory: @\Doctrine\ORM\EntityManager::getRepository('Acme\User')

Teď si je můžu v pohodě předávat kam budu potřebovat.

class UsersPresenter extends BasePresenter
{
public function __construct(Doctrine\ORM\EntityRepository $users) {}

Ale, co kdybych je tam všechny registroval a chtěl si je nechat přes autowiring doplňovat? Nette mi to nedovolí, protože vidí jen XY služeb a všechny mají stejnou třídu. Spousta lidí to "řeší" tak, že třídu si podědí, pojmenuje ji UsersRepository a tu pak vyžaduje (nebo použije interface). Osobně tohle považuju za anti-pattern a dle mé zkušenosti to není dobrá cesta.

Někteří možná [znají ze staticky typovaných jazyků generika](http://en.wikipedia.org/wiki/Generic_programming) - když to hodně zjednoduším, tak jde o to, že si nadefinuji nějakou základní třídu, která "obaluje" chování nad určitým typem objektu, jako je třeba náš repozitář. Já mu řeknu, že má pracovat s entitou uživatele a on podle toho skládá dotazy.

Když naučíme Nette DIC rozlišovat, s jakým typem služba pracuje, můžeme si ušetřit práci s konfigurací a nechat si vše předat pomocí autowire. Přesně to (mimo jiné) dělá tento pull request.

Upravím si tedy definici služby

services:
usersRepository:
class: Doctrine\ORM\EntityRepository
factory: @\Doctrine\ORM\EntityManager::getRepository('Acme\User')

a doplním annotaci do presenteru

class UsersPresenter extends BasePresenter
{
/** @param Doctrine\ORM\EntityRepository $users */
public function __construct(Doctrine\ORM\EntityRepository $users) {}

V tenhle moment už Nette umí rozlišit, která služba je která a správně je automaticky doplní.

Diskuzi prosím směřujte pod RFC: