pouziti DI zakladni priklad

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

Ahoj, chtej jsem si zkusit pouzit DI a jel jsem podle dokumentace…tam se ale pouziva context coz jak David rika ve svem videu neni uplne ono a v jeho videu o DI se predstavuje vse jen okrajove…neni prosim nekde nejaky komplet priklad nebo postup jak vse spravne nastavit a predavat spravne?

Diky

spiider
Člen | 162
+
0
-

Na toto jsem koukal, ale musim vytvaret tu tridu Container? Myslel jsem ze toto vsechno by se mohlo nacist z config.neon a to prave nevim kdyz si vsechny zavislosti predam a v configu zaregistruju sluzbu jak ji pak ziskat v presenteru. Koukal jsem i tady:
https://pla.nette.org/…ect-autowire

Tak sem ted zmateny trosku, protoze vsude to je trosku jinak udelane a nevim co je spravny postup.

Diky

Šaman
Člen | 2640
+
0
-

Ta třída Container se ti právě stará o vytvoření tříd z configu a o autowiring při vytváření tříd se závislostmi. Jinak by sis toto musel řídit sám. A nakonec by sis nějaký Container psal vlastní (kde bys jinak vytvářel třídy z informací, které načteš v configu? Někde musíš ty služby vytvořit a injectnout je ostatním.)

Jiří Nápravník
Člen | 710
+
0
-

Nejsem zrovna nějaký pokročilý v nette. Nicméně Container vytváříš v bootstrapu:

$container = $configurator->createContainer();

tím máš všechny služby načtený.

Pak si v presenteru uděláš property:

private $property;

a metodu:

public function injectProperty(\Trida $p)
{
	$this->property = $p;
}

no a pak k tomu přistupuješ všude jinde přes $this->property->metoda(); atd

Editoval Jiří Nápravník (29. 6. 2013 20:58)

spiider
Člen | 162
+
0
-

Ja to zkousel presne podle navodu v dokumentaci a vytvoril jsem si staticky container. Ale nevim jak predat parametry z configu o pripojeni. Muj container vypada takto:

class DIContainer extends \Nette\DI\Container {

	protected function createServiceConnection()
	{
            return new \Nette\Database\Connection(
			$this->parameters['dsn'],
			$this->parameters['user'],
			$this->parameters['password']
		);

	}

	protected function createServiceUser()
	{
		return new \Models\UserModel($this->connection);
	}

}

ale ladenka mi vraci ze $this->parameters je prazdne.

tady je vycuc z meho config.neon:

common:
	parameters:
		database:
			driver: mysql
			host: localhost
			username: root
			password: ****
			dbname: mojedb
	nette:
		application:
			errorPresenter: Error

		database:
			default:
				dsn: "%database.driver%:host=%database.host%;dbname=%database.dbname%"
				user: %database.username%
				password: %database.password%
	services:

		routerFactory: RouterFactory
		router: @routerFactory::createRouter

		#ostatni sluzby
		userModel: Models\UserModel

O tom injectProperty v dokumentaci zminka neni, je o tom psano v sekci planette, tak ted nevim jak a co pouzit. Diky moc za rady

Editoval spiider (2. 7. 2013 9:31)

frosty22
Člen | 373
+
0
-

Koukám trošku zmatené, ale ten návod, co jsi četl tak to je popis toho kontajneru obecně a jak to funguje, ten kontajner je v nette, ale již hotová a nemusíš ho vytvářet a hlavně není ani proč to dělat.

NEON soubor je v podstatě jiný zápis toho kontajneru – abys nemusel si vytvářet ten object Container a v něm definovat ty metody, předávat závislosti, parametry atd. Tak to zapíšeš do NEONu a Nette již vygeneruje ten kontajner samo.

Takže to DIContainer zahoď a zapiš to do toho NEONu, což v tvém případě tam dokonce již máš, čili například toto v NEONu:

userModel: Models\UserModel

Ti vygeneruje do kontajneru:

<?php
public function createServiceUserModel()
{
	return new Models\UserModel();
}
?>

Potom Nette když vytváří presenter, například tvůj HomepagePresenter, tak se podívá zda-li tam máš metody, které jsou veřejné a začínají inject .. pokud ano, tak je zavolá a předá jim požadovanou službu, čili například:

<?php
class HomepagePresenter extends Nette\UI\Presenter {

	private $userModel;

	public function injectUserModel(\Models\UserModel $model)
	{
		// Díky typehinting ví, že sem má předat službu \Models\UserModel
		$this->userModel = $model;
	}


	public function actionDefault()
	{
		$this->userModel->... // tady již mám tvou službu \Models\UserModel
	}

}

?>
frosty22
Člen | 373
+
0
-

A jen pro doplnění, tak zároveň nette ještě předá i samotný kontajner do presenteru a to do property context, s čímž se tady na foru potkáš často. Takže pokud bys v presenteru zavolal:

<?php
public function actionDefault()
{
	$this->context->userModel->... // toto je též tvůj objekt \Models\UserModel
}
?>

Ale toto není doporučené používat, jelikož by správně presenter neměl být závislý na kontajneru, ale to by již byla diskuze na dlouho a najdeš na to zde mnoho příspěvků :)