Posílání emailů, Nette\Mail\IMailer pomocí DI, TypeError
- ludek
- Člen | 83
Zdravím,
v dokumentaci se píše, že se mailer nemá vytvářet ručně, ale přes DI, tak jsem si do presenteru napsal:
class MailingPresenter extends BasePresenter {
use Nette\Mail\Message;
/** @var Nette\Mail\IMailer Mailer */
private $mailer;
public function __construct(Nette\Mail\IMailer $mailer) {
parent::__construct();
$this->mailer = $mailer;
}
// a někde později by bylo:
$mailer->send($mail);
}
Ale dostanu chybu:
TypeError:
Argument 1 passed to App\Presenters\BasePresenter::__construct() must implement interface Nette\Http\IRequest, none given
V BasePresenter
je
abstract class BasePresenter extends Nette\Application\UI\Presenter {
/** @var Nette\Http\IRequest Pro zjištění IP adresy */
public $httpRequest;
public function __construct(Nette\Http\IRequest $httpRequest) {
parent::__construct();
$this->httpRequest = $httpRequest;
}
protected function startup() {
parent::startup();
$this->ipaddress = $this->template->ipaddress = $this->httpRequest->getRemoteAddress();
}
}
A doteď to fungovalo normálně. Můžete mi prosím poradit, co dělám špatně? Díky.
- iNviNho
- Člen | 352
Nette\Mail\Message nie je traita, ale class, takže by mala
byť definovaná mimo triedy.
Nepoužíval by som constructor v presentery, ale zjednodušil si život
anotáciou @inject
To isté by som spravil pre IRequest.
<?php
use Nette\Mail\Message,
Nette\Mail\IMailer,
Nette\Http\IRequest;
class MailingPresenter extends BasePresenter {
/** @var IMailer Mailer @inject */
private $mailer;
/** @var IRequest @inject */
public $httpRequest;
protected function startup() {
parent::startup();
$this->ipaddress = $this->template->ipaddress = $this->httpRequest->getRemoteAddress();
}
}
?>
** spojil som to všetko do jedného presentra pre prehľad
Editoval iNviNho (25. 10. 2016 12:38)
- ludek
- Člen | 83
Díky moc za odpovědi. Teď tam mám inject metodu a je to zdá se v pořádku:
/** @var Nette\Mail\IMailer Mailer */
private $mailer;
public function injectMailer(Nette\Mail\IMailer $mailer)
{
$this->mailer = $mailer;
}
Do konstruktoru jsem to původně nacpal pro jistotu, protože je to povinná závislost. Také jsem párkrát četl, že „závislosti jedině konstruktorem a nikdy jinak“.
- iNviNho
- Člen | 352
Kde vidíš menej písania? :)
<?php
/** @var Nette\Mail\IMailer Mailer @inject */
private $mailer;
?>
alebo
<?php
/** @var Nette\Mail\IMailer Mailer */
private $mailer;
public function injectMailer(Nette\Mail\IMailer $mailer)
{
$this->mailer = $mailer;
}
?>
Akonáhle používaš @injecty(iba v presenteri), tak hned za class si vždy definuješ všetky závislosti(premenné) a hotovka…
Ak máš napr. 10 závislosti, tak budeš písať 10 funkcií? Troška sa upíšeš a znížiš prehľadnosť :-\
- CZechBoY
- Člen | 3608
To sou vždycky dohady jestli použít anotaci nebo metody …
Metody maj výhodu, že může mít BasePresenter svoje vlastní závislosti a
nikdo jinej k nim nemá přístup (private property).
Anotace má zas výhodu že je kratší zápis, ale přístup maj všichni
(public property).
Něco mezi může bejt Kdyby\Autowired kdy může bejt property i private… ale to už je hodně magie (kudy se tam vlastně ta instance dostane).
- ViPEr*CZ*
- Člen | 818
Do konstruktoru jsem to původně nacpal pro jistotu, protože je to povinná závislost.
To je vlastně pravda, jen to moc neplatí u Presenterů, protože instance vytváří nějak v pozadí Nette. Dokonce s instancema i samo pracuje. Těžko někde voláš členskou metodu Presenteru, maximálně někde uvnitř objektu přes this. Takže inject je jakási speciální syntaxe/vlastnost.
a je to přesně jak píše @CZechBoY