inject Latte\Engine v konzolové aplikaci

- supex
 - Člen | 2
 
Ahoj,
dělám teď na konzolové php aplikaci. Zatím umí jenom to, že z konzole
(Kdyby\Console) přebere parametry a vyflusne mi přes Latte vygenerovanou
šablonu, kterou pak použiju pro poslání mailu z powershellu.
<?php
protected function execute(InputInterface $input, OutputInterface $output) {
        $template=new Latte\Engine
		$params = [
            'from' => $input->getArgument('from'),
            'accounts' => $input->getArgument('accounts')
        ];
        $output->writeLn($template->renderToString(__DIR__ . '/templates/generatecreatemail/generatecreatemail.latte', $params));
    }
?>
Takhle mi to bez problému funguje.
Říkal jsem si, ale že zkusím dodržet DI „vstříkni to tam“. Udělal
jsem si abstraktní třídu MailCommand, která má přes @inject anotaci
vstříknuté Latte\Engine a tu pak chci dědit v Command třídách, které
budou mít za úkol generovat rozdílné maily
<?php
class MailCommand extends Command {
    /** @var \Latte\Engine @inject */
    public $template;
}
?>
Nicméně při spuštění mi nette, resp tracy, vyhodí následující
exception
`[Nette\InvalidStateException]
Service of type Latte\Engine used in @var annotation at
App\Console\MailCommand::$template not found. Did you register it in
configuration file?`
composer.json vypadá následovně
<script>
{
    "require": {
        "latte/latte": "^2.4",
        "kdyby/console": "^2.6",
        "nette/di": "^2.4",
        "nette/neon": "^2.4",
        "nette/bootstrap": "^2.4",
        "tracy/tracy": "^2.4"
    },
    "autoload": {
        "psr-4": {
            "App\\": [
                "app/"
            ]
        }
    }
}
</script>
Pokud jsem dobře pochopil bootstrap.php, tak Latte jako service nemusím uvádět v config.neon, protože už je načtené přes autoload.php z vendor složky. Navíc se nic nezmění když ho v neonu zaregistruju :/
Cache jsem mazal. Nic se nezměnilo.
Můžete poradit co dělám blbě? Případně trochu nasměrovat?
Appka bude čistě konzolová, takže nechci tahat celé nette.

- David Matějka
 - Moderator | 6445
 
latte engine neni registrovan jako sluzba. Je zde ale create: https://api.nette.org/…Factory.html, kterou si muzes predat.

- Jan Mikeš
 - Člen | 771
 
Latte\Engine totiž není služba, je vytvářena pomocí LatteFactory
edit: @DavidMatějka byl rychlejší :-)
Editoval Jan Mikeš (24. 10. 2016 12:34)

- Jan Mikeš
 - Člen | 771
 
@supex to vůbec ne, můžeš si vytvořit svou vlastní factory ;)
Ještě stojí za povšimnutí, jak latte extension lattefactory generuje automaticky:
public function loadConfiguration()
	{
		if (!class_exists(Latte\Engine::class)) {
			return;
		}
		$config = $this->validateConfig($this->defaults);
		$builder = $this->getContainerBuilder();
		$builder->addDefinition($this->prefix('latteFactory'))
			->setClass(Latte\Engine::class)
			->addSetup('setTempDirectory', [$this->tempDir])
			->addSetup('setAutoRefresh', [$this->debugMode])
			->addSetup('setContentType', [$config['xhtml'] ? Latte\Compiler::CONTENT_XHTML : Latte\Compiler::CONTENT_HTML])
			->addSetup('Nette\Utils\Html::$xhtml = ?', [(bool) $config['xhtml']])
			->setImplement(Nette\Bridges\ApplicationLatte\ILatteFactory::class);
		$builder->addDefinition($this->prefix('templateFactory'))
			->setClass(Nette\Application\UI\ITemplateFactory::class)
			->setFactory(Nette\Bridges\ApplicationLatte\TemplateFactory::class);
		foreach ($config['macros'] as $macro) {
			if (strpos($macro, '::') === FALSE && class_exists($macro)) {
				$macro .= '::install';
			}
			$this->addMacro($macro);
		}
		if ($this->name === 'latte') {
			$builder->addAlias('nette.latteFactory', $this->prefix('latteFactory'));
			$builder->addAlias('nette.templateFactory', $this->prefix('templateFactory'));
		}
	}
					Editoval Jan Mikeš (24. 10. 2016 12:50)