Jak předat vlastní třídě aplikace DI container?

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

Zdravím,
mám třídu MyApplication, která dědí od Nette\Application\Application, a potřebuju jí předat DI container. Mám Nette 2.0.10. Jde mi konkrétně o tohle:

  1. Když budu mít container nadefinovaný jako službu
$container->addService('context', function($container) {
    return $container;
});

a v configu

application:
        class: MyApplication
        arguments: [@container]

předpokládám, že se předá parametr container konstruktoru třídy. Co se ale pak stane se závislostmi rodičovské třídy Application? Taky mi není úplně jasné, jak tohle přesně funguje, když se config.neon použije při vytvoření containeru a služba container se přidá až následně – odkud se vezme parametr container při vytváření containeru, když v té době ještě služba container není přidaná?

  1. Když použiju metodu injectContainer a budu spoléhat na autowire, bude to fungovat? Nebo to v Nette 2.0.10 funguje jen pro presentery? Nette 2.1-dev používat nechci, raději si počkám na stable verzi.
  2. Existuje jiné rozumné řešení? Snažím se o striktní DI a nerada bych používala něco typu $GLOBALS[‚container‘], pokud se tomu můžu vyhnout.
Filip Procházka
Moderator | 4668
+
0
-

Musíš to udělat takhle

class MyApplication extends Nette\Application\Application
{
	private $container;

	public function __construct(
		IPresenterFactory $presenterFactory, IRouter $router,
		Nette\Http\IRequest $httpRequest, Nette\Http\IResponse $httpResponse,
		Nette\DI\Container $container)
	{
		parent::__construct($presenterFactory, $router, $httpRequest, $httpResponse)
		$this->container = $container;
	}

}

A konfigurace

services:
	application:
		class: MyApplication

Autowire se postará o zbytek :)

chikeet
Člen | 160
+
0
-

Díky :-) Škoda, že není nějaký hezčí způsob bez ručního předávání závislostí rodiče, ty injecty, o kterých se mluví v článku https://phpfashion.com/…-presenterum, by se mi docela líbily. Třeba časem… :-)

Editoval chikeet (12. 5. 2013 13:43)

Filip Procházka
Moderator | 4668
+
0
-

Tohle je nejhezčí možný způsob ;) Pokud použiješ kvalitní IDE, třeba PhpStorm, tak ti umí takový kód vygenerovat na dvě kliknutí :)

Inject metody fungují už teď, ale jsou určené presenterů, tady si můžeš přečíst proč.

chikeet
Člen | 160
+
0
-

Pravda. Hledala jsem způsob, jak se vyhnout constructor hell, a zapomněla při tom, proč se mi constructor injection původně líbilo nejvíc. Univerzální ideální řešení holt většinou neexistují…

Mimochodem díky za tip na IDE :-)

Filip Procházka
Moderator | 4668
+
0
-

Jedna úroveň dědičnosti je ještě v pohodě. Constructor hell začíná u dvou :)

chikeet
Člen | 160
+
0
-

To je právě ono… U presenterů mám i tři úrovně dědičnosti (to by možná taky zasloužilo vylepšit), jinak naštěstí maximálně dvě. Šlo mi o to, najít nějaké univerzální řešení DI, použitelné pro presentery i všechno ostatní. Ale vidím, že zrovna tady by se mi to spíš vymstilo.