Dependency Injection, jako samostatný modul

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

Ahoj,

snažím se do jednoho mého projektu co je mimo nette dostat DI. Nainstaloval jsem DI přes composer ve verzi 2.4.6. Rozchodit jsem se to smažil přesně dle dokumentace na githubu https://github.com/nette/di.

Povedla se mi rozchodit ta část, kde se závislost předává pomocí konstruktoru

$loader = new Nette\DI\ContainerLoader(__DIR__ . '/temp');
$class = $loader->load(function($compiler) {
    $compiler->loadConfig(__DIR__ . '/config.neon');
});
$container = new $class;
$manager = $container->getByType(App\Model\Test::class);

to funguje skvěle.

Ovšem dále jsem se snažil rozchodit tu část, kde závislost předávám pomoci anotace @inject nebo metody inject* to se mi ovšem podařit nepodařilo, nikdy to samo nedoplní do té proměnné tu závislost.

Můj config vypadá takto

services
Storevio\App\Model\Test2
Storevio\App\Model\Test

service3:
class: App\Service3
inject: yes

Service 3 pouze takt jednoduše (pouze pro test)

namespace App;


class Service3{

    /** @var Model\Test @inject */
    public $test;

    public function get(){
        return $this->test->get();
    }

}

A celý kod volání té závislosti

	$loader = new Nette\DI\ContainerLoader(__DIR__. '/cache/temp', true);
$class = $loader->load(function($compiler) {
    $compiler->loadConfig(STOREVIO_DIR . '/config/config.neon');
});

$container = new $class;
$manager = $container->getService('service3');
echo $manager->get();

Vše by tedy mělo být dle dokumentace správně.

Máte s tím někdo zkušenost, jak to rozchodit takto samostatně?

Děkuji.

Tomáš Votruba
Moderator | 1114
+
0
-

Inject se hodí pouze do abstract tříd jako prevence constructor hell.

Tady bych použil přímo constructor.

https://phpfashion.com/…i-zavislosti

Marek K.
Člen | 8
+
0
-

Ano souhlasím, ale jak píši je to pouze test zda vůbec @inject bude fungovat a zatím, i když je to dle dokumentace tak nefunguje a nepodařilo se mě přijít na to proč. Pokud jsem porovnal vygenerovanou třídu pro DI když to použiji samostatně a když tu třídu vygeneruje přímo NETTE, tak je $meta naprosto shodná. Liší se pouze v metodách createService_* kde to vygeneruje jen instanci, ale už to tam nedodá volání $service->inject*.

CZechBoY
Člen | 3608
+
0
-

Zkus si přidat inject extension (nevim jestli se načítá sama od sebe, ale řekl bych, že za to může spíš nějakej můstek mezi application a di).

extensions:
	- Nette\Di\Extensions\InjectExtension
Marek K.
Člen | 8
+
0
-

@CZechBoY díky za posun, pro zápis v configu extensions to vracelo chybu, že to extensions nezná, ale tvůj komentář mě posunul správným směrem.

Aby to fungovalo, tak je třeba upravit volání takto

$loader = new Nette\DI\ContainerLoader(__DIR__. '/cache/temp', true);
    $class = $loader->load(function($compiler) {
        $compiler->addExtension('inject', new Nette\DI\Extensions\InjectExtension);
        $compiler->loadConfig(__DIR__. '/config/config.neon');
    });

Případně použít tvůj zápis v configu, ale pak je nutné v mít ten kód takto

$loader = new Nette\DI\ContainerLoader(__DIR__. '/cache/temp', true);
    $class = $loader->load(function($compiler) {
        $compiler->addExtension('extensions', new Nette\DI\Extensions\ExtensionsExtension);
        $compiler->loadConfig(__DIR__. '/config/config.neon');
    });

Ještě jednou díky