Predanie závislosti do class od modelu
- iNviNho
- Člen | 352
Ahojte, mám menší problém, kedy v Presentery sa snažím vytvoriť a registrovať uživateľa
DomovPresenter
<?php
$uzivatel = new Uzivatel();
$uzivatel->naplnPodlaDat($v["meno"], $v["priezvisko"], $v["mail"], $v["heslo"]);
$uzivatel->registrujUzivatela();
?>
Trieda Uzivatel potom vytvorí uživateľa, naplní data a registruje ho. Problém prichádza pri registrácií, kde chcem využiť UzivateliaRepository a neviem ako túto Repository pridať do triedy Uživatel
class Uzivatel
<?php
/** @var Model\UzivateliaRepository @inject */
public $uzivatelia;
public function naplnPodlaDat( $meno, $priezvisko, $mail, $heslo) {
$this->meno = $meno;
$this->priezvisko = $priezvisko;
$this->mail = $mail;
$this->heslo = $heslo;
}
public function registrujUzivatela() {
$data = array($this->meno, $this->priezvisko, $this->mail, sha1($this->heslo));
$this->uzivatelia->vytvorUzivatela($data); // ERROR, call to a member function on null ...
}
?>
Chyba je logická, injectovať mimo presenter sa nedá a teda v $this->uzivatelia je NULL, ale ako teda šikovne poriešiť predanie tejto závislosti?
config.neon
<?php
services:
- App\Model\UserManager
- App\Forms\SignFormFactory
Uzivatelia: App\Model\UzivateliaRepository
- Web\FrontModule\Uzivatel (App\Model\UzivateliaRepository)
router: App\RouterFactory::createRouter
?>
Skúsil som to takto a vyhadzuje mi to, že Uzivatel nemám konstruktor, tak
som ho pridal
Uzivatel
<?php
public function __construct(Model\UzivateliaRepository $uzivatelia) {
$this->uzivatelia = $uzivatelia;
}
?>
No a teraz hádže error, že som tomu new Uzivatel nedal parameter, ale nepáčilo by sa mi keby som ho tam v presenteri musel pchať, ako teda na to?
Ďakujem dakujem dakujem!
- Mysteria
- Člen | 797
Problém máš v tom, že bys v presenteru neměl nikdy vytvářet třídu
sám přes new.
Pokud bys trval na svém řešení, tak ti nezbyde nic jinýho, než tam ten
parametr dopsat ručně.
Potřebuješ tam vůbec tu třídu Uzivatel? Já osobně bych tu metodu registrujUzivatela dal normálně do UzivateliaRepository, kterou bych si injectnul do presenteru a pak už jednoduše:
$this->uzivateliaRepository->registrujUzivatela($name, $nick, $mail, $password);
A ještě místo sha1() by bylo bezpečnější použít \Nette\Security\Passwords::hash().
- iNviNho
- Člen | 352
Mysteria napsal(a):
Problém máš v tom, že bys v presenteru neměl nikdy vytvářet třídu sám přes new.
Pokud bys trval na svém řešení, tak ti nezbyde nic jinýho, než tam ten parametr dopsat ručně.Potřebuješ tam vůbec tu třídu Uzivatel? Já osobně bych tu metodu registrujUzivatela dal normálně do UzivateliaRepository, kterou bych si injectnul do presenteru a pak už jednoduše:
$this->uzivateliaRepository->registrujUzivatela($name, $nick, $mail, $password);
A ještě místo sha1() by bylo bezpečnější použít \Nette\Security\Passwords::hash().
Jasné, že to nepotrebujem robiť cez to a môžem to spraviť tak ako hovoríš, ale to proste nie je tak prehľadné a čisté, ako by som to chcel mať :)
- Luděk Veselý
- Člen | 29
Moznosti je vice, pokud chces nejak dostat UzivateliaRepository
do tridy Uzivatel
, kterou vytvaris operatorem new
, tak
ji tam dostanes z presenteru:
# config.neon
services:
- App\Model\UserManager
- App\Forms\SignFormFactory
- App\Model\UzivateliaRepository
- Web\FrontModule\Uzivatel
router: App\RouterFactory::createRouter
namespace Web\FrontModule;
class Uzivatel
{
/** @var Model\UzivateliaRepository */
public $uzivatelia;
public function __construct(Model\UzivateliaRepository $repo)
{
$this->uzivatelia = $repo;
}
public function naplnPodlaDat...
// ... dalsi metody
}
namespace App\Presenters;
class DomovPresenter
{
/** @var Model\UzivateliaRepository */
public $uzivatelia;
public function __construct(Model\UzivateliaRepository $repo)
{
$this->uzivatelia = $repo;
}
public function actionDefault()
{
$uzivatel = new Uzivatel($this->uzivatelia);
$uzivatel->naplnPodlaDat($v["meno"], $v["priezvisko"], $v["mail"], $v["heslo"]);
$uzivatel->registrujUzivatela();
}
}
Jak vidis tak to neni uplne nejpohodlnejsi, vytvoril bych si nejakou servisni tridu, ktera by si v konstruktoru vynutila repository a mela by metodu ktera by vracela nove instance uzivatelu. Zhruba takto:
class UserService
{
/** @var Model\UzivateliaRepository */
public $uzivatelia;
public function __construct(Model\UzivateliaRepository $repo)
{
$this->uzivatelia = $repo;
}
public function getUser()
{
return new \Web\FrontModule\Uzivatel($this->uzivatelia);
}
}
pridat do configu a upravit presenter:
class DomovPresenter
{
/** @var UserService */
public $service;
public function __construct(UserService $service)
{
$this->service = $service;
}
public function actionDefault()
{
$uzivatel = $this->service->getUser();
$uzivatel->naplnPodlaDat($v["meno"], $v["priezvisko"], $v["mail"], $v["heslo"]);
$uzivatel->registrujUzivatela();
}
}
Neresim namespace a asi tam budou chyby, ale snad je to pochopitelne.. Dalsi
moznosti by bylo mit uzivatel
bez toho repository a volat
$uzivatel->registrujUzivatela($uzivatel);
.
- newPOPE
- Člen | 648
Este si mozes urobit factory na to. A potom len :
class Uzivatel {
public function __construct($meno, $prie, $foo, $bar, UserRepository $repository) {
// tu by si mal najst vsetko
// posledny parameter by mal vyriesit DI container za teba
}
}
// namiesto new Pouzivatel(); v Presenteri si @inject-om predas repository...
$this->userFactory->create($meno, $prie, $foo, $bar);
// UserFactory
interface IUserFactory {
// @return Pouzivatel
public function create ($meno, $prie, $foo, $bar);
}
Editoval newPOPE (7. 8. 2015 16:39)