Email sender – ITemplateFactor sa neinjectne

MKI-Miro
Člen | 279
+
0
-

Ahojte

Mám takýto EmailSender

<?php

declare(strict_types=1);

namespace App\Helpers;

use Nette;
use Nette\DI\Attributes\Inject;
use Nette\Application\LinkGenerator;
use Nette\Application\UI\ITemplateFactory;
use Nette\Mail\Message;
use App\Language\Translator;

class MailSender
{
    #[Inject]
    public LinkGenerator $linkGenerator;

    #[Inject]
    public ITemplateFactory $templateFactory;

    public function createTemplate(): ITemplate
    {
        $template = $this->templateFactory->createTemplate();
        $template->getLatte()->addProvider('uiControl', $this->linkGenerator);

        return $template;
    }

    public function resenderVendorOrderEmail(string $lang, $params): Message
    {
        $translator = new Translator($lang);

        $template = $this->createTemplate();
        $template->setTranslator($translator);

        $html = $template->renderToString(__DIR__ . '/templates/Checkout/email_vendor_resend.latte', $params);

        $mail = new Message();
        $mail->setHtmlBody($html);

        return $mail;
    }
}

Dostávam ale chybu

Typed property App\Helpers\MailSender::$templateFactory must not be accessed before initialization

Je nejaký dôvod prečo sa neinjectne?

Ďakujem

David Matějka
Moderator | 6445
+
+1
-

Ahoj, inject anotace a metody fungují defaultně pouze v presenterech, viz doc: https://doc.nette.org/…dependencies

Další techniky, tedy metody inject* a členské proměnné označené anotací @inject, jsou pak méně čisté techniky a jsou dostupné jen v presenterech, případně je možné je vynutit konfigurací u služeb vytvářených DI Containerem

MKI-Miro
Člen | 279
+
0
-

Dakujem

takze pridanie do configu pomohlo

	mailSender:
		create: App\Helpers\MailSender
		inject: true
Šaman
Člen | 2667
+
+4
-

Jen pro pořádek – mělo by se to řešit konstruktorem. Jsou to závislosti, bez kterých MailSender nebude fungovat.
Autoinject pomocí anotací (nebo nově tagů) je taková Nette obezlička pro rychlé vkládání závislostí do presenterů (které jsou trochu mimo klasické třídy modelové vrstvy, jako třeba ten MailSender).

h4kuna
Backer | 740
+
0
-

jak píše @Šaman představ si, že v tvém případě jde udělat

$sender = new MailSender;
dump($sender);

A vznikne instance, aplikace nespadne (což je velmi špatně). Ale už nebude fungovat

$sender->createTemplate();

Protože jsi nesplnil závislosti. Proto se to dělá přes konstruktor, aby právě nešla vytvořit instance třídy bez toho, aniž by jsi ji správně naplnil.

Editoval h4kuna (6. 1. 2021 8:30)