Dependency Injection, jako samostatný modul
- Marek K.
- Člen | 8
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
Inject se hodí pouze do abstract tříd jako prevence constructor hell.
Tady bych použil přímo constructor.
- Marek K.
- Člen | 8
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*.
- Marek K.
- Člen | 8
@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