Nette 2.1dev – jak správně a čistě dostat do komponenty přístup do db
- motorcb
- Člen | 552
Zdravim.
Používám komponentu Login pro vykreslení přihlašovacího formuláře a
přihlášení uživatele.
Ovšem nevím jak dostat do komponenty přístup do databáze.
namespace Component;
use Nette;
use Nette\Application\UI\Form;
class Login extends Nette\Application\UI\Control
{
public function __construct()
{
parent::__construct();
}
protected function createComponentLoginForm()
{
$form = new Form();
$form->addText( 'nick', 'Nick:', 26, 20 );
$form->addPassword( 'password', 'Heslo:', 26 );
$form->addSubmit( 'login', 'Přihlásit se' );
$form->onSuccess[] = $this->loginFormSubmitted;
return $form;
}
public function loginFormSubmitted( Form $form )
{
//TODO - jak se dostanu k databazi?
}
public function render()
{
$this->template->setFile( __DIR__ . '/Login.latte' );
$this->template->render();
}
}
Je správné řešení si předávat v konstruktoru službu poskytující
přístup k tabulce s uživateli ($this->userRepository)?
Nebo mi doporučíte lepší řešení?
- Šaman
- Člen | 2666
Jsou dvě čisté možnosti, obě jsou DI.
- Jedna možnost je konstruktor injection a ano, je to čistý a doporučovaný způsob.
- Pokud bys z nějakých důvodů nechtěl použít konstruktor, tak použij
setter injection. Napiš si setter a pokud chceš, aby se závislost předávala
automaticky, pojmenuj ho
inject*
. Inject metody se ve verzi 2.1 zavolají automaticky ihned po vytvoření instance kontejnerem. - Pokud bys náhodou někdy vytvářel instanci ručně, tak bys musel ručně také předat závislosti, ať už do konstruktoru, nebo pomocí té metody.
- motorcb
- Člen | 552
Šaman:
Díky za info.
konstruktor injection nevyužiji, protože je to komponenta tu musím
inicializovat.
Nehledě na to, že kdybych chtěl v budoucnu v této komponentě přistupovat
i k jiným repository, musel bych upravit všechny metody kde se volá
komponenta Login:
Asi neexistuje možnost nadefinovat komponentu automaticky aby si přes DI
natahla požadované závislosti,co?
protected function createComponentLogin()
{
return new Component\Login( TADY_BYCH_MUSEL_PREDAVAT_ZAVISLOSTI );
}
Jak bych měl použít ten setter injection?
Díky
- Šaman
- Člen | 2666
Ten problém je docela dopodrobna
rozebrán na fóru
Aktuální stav a ukázkové
řešení je tady
Cílem je minimalizovat volání operátoru new a nechat většinu instancování a řešení závislostí na kontejneru. Pak nemusíš přepisovat nic, jen ten jeden konstruktor. O ostatní se postará aplikační kontejner a jeho správa závislostí.
// Mimochodem v té druhé ukázce je i příklad setter injection,
v tomto případě do presenteru (tam totiž může být s použitím
konstruktoru problém). Jedná se o tu metodu
injectShowBasketFactory
. Je jedno, jak se bude jmenovat, ale musí
začínat na inject* (aby ji automaticky zpracoval autowiring) a musí být
uveden typ požadovaného parametru (zde třída ShowBasketFactory), podle
které se dohledá odpovídající služba v kontejneru a předá se.
Editoval Šaman (13. 6. 2013 20:54)