Dotaz ohledně injektování služeb

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
Spectrik
Člen | 23
+
0
-

Ahoj,

mám ve třídě konstruktor

public function __construct(Nette\Database\Context $database)
    {
        $this->database = $database;
    }

Když se podívám do API, tak Nette\Database\Context bere v konstruktoru Nette\Database\Connection. Zajímá mě kde konkrétně se do proměnné $database vloží právě objekt třídy Nette\Database\Connection aby to mohlo fungovat? Funguje to tak? Chápu to dobře? Je to pro mě důležité pro dobré pochopení frameworku. Díky moc předem za odpovědi.

Editoval Spectrik (26. 8. 2014 20:34)

David Kudera
Člen | 455
+
0
-

Funguje to jednoduše díky di . V nette je registrováno několik služeb. Včetně databáze nebo tvých vlastních služeb, které zapisuješ do konfigurace v sekci services.

Tyhle služby (třídy) nette projde, zkontroluje konstruktory (nejen ty) a pokusí se zjednodušeně dosadit pasující služby (pokud nejsou nastavovány ručně).

Ve skutečnosti je to trochu složitější. Třeba u presenterů kontroluje i inject* metody a public property s inject anotací. Dále jsou tu továrničky, rozšíření a spousta dalších věcí. Tohle všechno nette jak jsem říkal zkontroluje a vytvoří klasický php kód. Co vznikne, můžeš vidět v temp složce, kde je složka configurator nebo tak nějak. Tam i najdeš kód, který dá vzniknout například kompletní službě database.

To co je v tomhle tempu je to, čím to celé může fungovat. Proto si stačí cokoliv vyžádat v konstruktoru a je tu jistota, že to dostanu. Nemusím přemýšlet nad tím, kde vzít nějaký connection, který bych dal contextu. To udělá nette.. Já jen vím, že chci context.


Snad jsem to nenapsal nějak zmatečně třeba :-)

Spectrik
Člen | 23
+
0
-

Ještě mě napadá…když mám v konfiguráku toto:

nette:
	database:
		dsn: 'mysql:host=127.0.0.1;dbname=spectrik'
		user:  root
		password: root
		options:
			lazy: yes

Tak je možné že tedy ta proměnná $database odpovídá database v tom cofiguráku? Protože jestli ne tak to furt nechápu :D

Editoval Spectrik (26. 8. 2014 21:08)

David Kudera
Člen | 455
+
0
-

No tohle je zrovna „speciální příklad“. Celá ta sekce nette, je rozšířením , což je nějaká třída, která může sama registrovat další služby, editovat existující.. No prakticky cokoliv. A právě ta sama ‚na pozadí‘ si tu database službu registruje…

Jsem si ale jistý, že když se zamyslíš jen nad sekcemi services a parameters, tak to bude o dost jednoduší ;-) Ty ostatní můžeš brát jednoduše jako nějaký nastavení. Nemusíš služby registrovat sám, ale udělá to za tebe rozšíření. Ty jen dodáš pár nějakých parametrů (právě třeba připojení k db)..

Šaman
Člen | 2666
+
0
-

Tenhle zápis v konfiguráku ti vytvoří v DI containeru novou instanci Nette\Database\Context. Ta je v celém kontejneru jen jedna a tak, když v tom DI kontejneru, tedy pomocí konfiguráků vytváříš třídu, která chce v konstruktoru předat Nette\Database\Context, tak se použije.

Když tuhle třídu bydeš vytvářet ručně pomocí operátoru new, tak jí tu $database musíš předat sám.

Takže na otázku Kde konkrétně se předá? je odpověď: V DI kontejneru při vytváření té třídy. Pokud DI kontejner má k dispozci právě jednu instanci Nette\Database\Context. (Kdyby ji neměl, nebo jich měl víc, hodí to chybu.)

Spectrik
Člen | 23
+
0
-

Díky všem. Od šamana jsem to pochopil :) nebo aspoň myslím že ano :D

Spectrik
Člen | 23
+
0
-

Poslední otázka: Kde můžu najít svůj DI kontejner? Chci vidět jak vypadá :)

David Kudera
Člen | 455
+
0
-

Aspoň od někoho :-D jinak ten vygenerovaný kontejner je právě v tom tempu, jak jsem psal ;-)

Spectrik
Člen | 23
+
0
-

@DavidKudera díky