Context, Services, Dependency Injections – help

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
David Růžička
Člen | 43
+
0
-

Přečetl jsem si něco o dependency injections a pokusil se to aplikovat na původní ukázkovou aplikaci Todolistu, kterou jsem zatím převedl pod nejnovější verzi frameworku. Jsem z toho ale poněkud zmatený a nemůžu se nikde dohledat informací o tom, jak to správně používat. Asi bude nejlepší řešit to po krocích, takže

problém 1 – databáze:

V konfigu se mi podařilo nakonfigurovat db:

common:
	services:
		model:
			class: TodoManager
			arguments: ["@database"]
		database:
			class: Nette\Database\Connection
			arguments: ['mysql:host=localhost;dbname=todolist', 'root', '']

Prvně jsem měl problém jak tu databázi nadefinovanou v konfigu získat uvnitř třídy modelu TodoManager, ale přišel jsem na to, že jde propasírovat v parametru konstruktoru (ten jsem tam musel dodělat). Připojení jsem si pak uložil do statické proměnné třídy (jako to bylo v původním examplu). Až potud ok. Výpis položek Todo fungoval správně.

Když chci položku otevřít pro editaci, tak ale nastává tento problém: V bootstrapu mám nadefinovanou routu, která id položky v db překládá na „slug“, který je u každé položky také nadefinován v db. Proto v routě používám statické callbacky (metody TodoManager) FILTER_IN a FILTER_OUT. Protože jsou ale statické, tak se nevolá konstruktor (nebo asi volá, ale až později) a já tedy nemám uloženo připojení k db, které mi normálně přichází právě v konstruktoru.

V tuto chvíli netuším, jak ono připojení (Nette\Database\Connection) v těchto callback metodách získám. Zkoušel jsem z těchto metod volat něco takového:

$configurator = new Nette\Configurator;
$application = $configurator->container->application->getContext()->getService('database');

ale hlásí mi to, že service ‚database‘ nemůže najít. Chci se vyvarovat použití nějakých globálních proměnných (ani si už nejsem jistý, jestli by to pomohlo) a Environment (když už je prý deprecated) a chtěl bych to udělat „správně“, ale fakt tápu.

voda
Člen | 561
+
0
-

David Růžička napsal(a):

Připojení jsem si pak uložil do statické proměnné třídy

Do statické proměnné to nedávej, není to potřeba.

Proto v routě používám statické callbacky (metody TodoManager) FILTER_IN a FILTER_OUT.

Tak nepoužívej statické, ale normální metody. Jako callback předáš:

array($configurator->container->getService('model'), 'nestatická metoda');

Editoval voda (13. 6. 2011 20:37)

David Růžička
Člen | 43
+
0
-

Super, to zafungovalo. Díky.

Ještě bych se zeptal: Jak z různých částí aplikace „správně“ v souladu s DI získám hodnoty z configu?

Filip Procházka
Moderator | 4668
+
0
-

musíš do nich předat context, nebo ty hodnoty z configu

$presenter->context->params['database'];
David Růžička
Člen | 43
+
0
-

Ok, chápu. Díky.