Co použít místo inject*()?

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

Ahoj,
použil jsem inject*() a nestačil jsem se divit, co všechno to dělá.

  1. volá se vždy (i když se proměnná nepoužije, není lazy)
  2. volá se v pořadí odspodu nahoru, takže je úplně jedno jak se pojmenuje
  3. volá se rychleji než startup()

Což jsou dosti podstatné problémy.

V BasePresenter-u si chci injektnout třídu, která obaluje model, takže bych potom z presenteru volal

$this->model->category->metoda()

Má to ovšem háček, že já té třídě potřebuji předat ID jazyka, který se používá.
A to právě není v inject*() možné, protože se volá ještě před startup() a nemůžu tedy nastavit jazyk, protože ho ještě nevím.

Ideální by pro měl bylo použít:

getModel(Model $m) // předá třídu podle typehint
{
	if(!$this->_model){
		$m->setLang($this->langID);
		$this->_model = $m;
	}
	return $this->_model;
}

Bylo by to lazy, takže by se ten model vytvořil až v momentě, kdybych potřeboval něco z DB.

Existuje něco takového ?

Tomáš Jablonický
Člen | 115
+
0
-

Tak si injectni továrničku a až budeš potřebovat „model“ tak si ho vytvoř:

<?php

protected $factory;

public function injectFactory($factory)
{
	$this->factory = $factory;
}

public function actionDefault()
{
	$model = $this->factory->create();
	$mode->setLang($this->lang);
	....
}

?>

Factory:

<?php

class Factory extend \Nette\Object
{

	public function craete()
	{
		return new Model();
	}
}

?>

Instance class factory bude existovat vždy (pokud je v neonu) a clas Model se vytvoří až teprve když to budeš potřebovat.

David Matějka
Moderator | 6445
+
0
-

pro lazy predavani zavislosti do presenteru muzes pouzit autowired z kdyby
ale to, ze se sluzba nepouzije, by se prilis stavat nemelo. pokud se ti do presenteru injectuje hodne sluzeb, ktery pouzijes jen nekdy (treba v ruznych akcich), je lepsi presenter rozdelit na mensi presentery :)

proc ten lang nenastavis ve startup? od toho prave startup je :)

Myiyk
Člen | 321
+
0
-

já jazyk ho nastavuji ve startup, takže právě proto není v době injectu nastaven, protože startup ještě neproběhl

Tomáš Jablonický
Člen | 115
+
0
-
<?php

	protected $model;

	public function injectModel($model)
	{
		$this->model = $model;
	}

	protected function startup()
	{
		parent::startup();
		$this->model->setLang($this->lang);
	}

?>

tohle nefunguje?

Myiyk
Člen | 321
+
0
-

Funguje, ale ta obalová třída si injectuje konkrétní modely, takže bych musel ten jazyk nějak předat i jim.

Díky za nakopnutí, předělám to. Budu injektovat přímo modely které v dané třídě použiji a po rozpoznání jazyka jej nastavím.

duke
Člen | 650
+
0
-

Metody inject* by měli pouze injektovat, nikoli konfigurovat injektované.

MartinitCZ
Člen | 580
+
0
-

@**Myiyk**: Přesně, jak píše duke. Vypadá to na chybu návrhu ;)

Myiyk
Člen | 321
+
0
-

Má někdo nějaké řešení, jak modelu předat jazyk?
S tím, že se to předání může provést, až v momentě kdy ve startup() ten jazyk zjistím.

Filip Procházka
Moderator | 4668
+
0
-

Jazyk zjišťuj v routeru a při Application::onRequest ho nastavuj své překladové službě.