Jak předat argument připojení
- ForestCZE
- Člen | 209
Ahoj, rád bych se zeptal, jak na to. Mám:
class Connection
<?php
namespace App\Model;
use Nette\Database\Context;
class Connection
{
/** @var Context */
protected $connection;
/** @var array */
private $services = [];
public function __construct(Context $connection)
{
$this->connection = $connection;
}
/** @return Context */
public function getConnection()
{
if (!isset($this->services['connection'])) {
$this->services['connection'] = $this->connection;
}
return $this->services['connection'];
}
}
V configu:
- App\Model\Connection
Poté class Rating, kde potřebuju to připojení:
<?php
namespace App\Model;
class Rating {
private $pripojeni;
public function __construct(Connection $pripojeni)
{
$this->pripojeni = $pripojeni->getConnection();
}
public function UpdateRating()
{
$this->pripojeni->table('rates')->fetch();
}
}
A nakonec v jednom presentru v handle metodě:
$update = new \App\Model\Rating($pripojeni);
$update->UpdateRating();
A jde o to, že musím inicializovat tu proměnnou $připojení
Takže nad tu první instanci bych dal něco jako:
$pripojeni = new \App\Model\Connection();
Nevím, jestli je to dobře a co by tato instance měla mít za argument. Dokáže mi někdo pomoct? Děkuji předem.
- CZechBoY
- Člen | 3608
V presenteru si to injectneš klasicky přes konstruktor nebo přes inject*
metodu – žádný new XxxService
nedělej pokud je to
služba!
K čemu má vlastně sloužit třída Connection
?
ps. ještě nějaký odkazy do dokumentace ohledně DI
https://doc.nette.org/…introduction
https://doc.nette.org/…dependencies
Editoval CZechBoY (31. 10. 2017 18:46)
- ForestCZE
- Člen | 209
CZechBoY napsal(a):
V presenteru si to injectneš klasicky přes konstruktor nebo přes inject* metodu – žádný
new XxxService
nedělej pokud je to služba!K čemu má vlastně sloužit třída
Connection
?ps. ještě nějaký odkazy do dokumentace ohledně DI
https://doc.nette.org/…introduction
https://doc.nette.org/…dependencies
Z jakého důvodu to nemůže být pomocí new? Není to služba, je to prostě třída, ve které chci zavolat metodu jen v handle metodě.
K čemu slouží třída Connection? Tak abych se připojil k databázi, ne? Pokud ses spletl a chtěl ses zeptat na třídu Rating, tak ok, ale je jedno co bude dělat přesně. Řekněme, že vytáhne data z tabulky a zapíše je do jiné. Ale potřebuji zrealizovat to připojení.
- ForestCZE
- Člen | 209
CZechBoY napsal(a):
Aha, tak potom – Proc ta trida neni sluzba?
No Connection jen vezme nette Connection a zas to vrati tak moc nechapu k cemu takova vec je…
Musí být snad každá třída službou?
Tak potřebuju se připojit k databázi, abych s ní mohl pracovat, nevím, co je na tom k nepochopení.
- Mysteria
- Člen | 797
Nechtěl jsi spíš napsat něco takovéhleho?
namespace App\Model;
use Nette\Database\Context;
class Rating {
/** @var Context */
private $database;
public function __construct(Context $database)
{
$this->database = $database;
}
public function updateRating()
{
$this->database->table('rates')->fetch();
}
}
A do config.neon do services přidej App\Model\Rating
.
A v presenteru pak budeš mít
/** @var Rating @inject */
public $rating;
$this->rating->updateRating();
Všimni si že nikde není použito ani jedno new, takže nemusíš řešit, co předávat do connection za parametry a podobně. O všechno se za tebe postará DI.
- ForestCZE
- Člen | 209
CZechBoY napsal(a):
No ze to pripojeni uz sluzba je.
Prosim precti si ty zaklady di.
Ano, Connection už služba je. Ale Rating není jediná třída, kde Connection používám. A myslel jsem, že se tu nemusíme dohadovat o tom, co je služba a co není. Vycházel jsem z toho, že nechci, aby Rating byla služba a chtěl jsem jenom poradit, jak předat to připojení. Nechápu, co je špatně na vytvoření instance.
- CZechBoY
- Člen | 3608
Uplne vsechno :-)
Treba nekdy v budoucnu budes chtit pridat dalsi zavislost pro tridu Rating.
Jelikoz uz budes mit na 50 mistech v kodu napsany
new Rating($connection)
tak to bude docela zabava na dlouhou noc.
Pokud bys ale mel sluzbu a pouzival tu tridu jako sluzbu tak bys zmenil jen
konstruktor (pripadne smazal cache) a je hotovo.
ps. indikatorem ze by trida mela byt sluzbou mi je to, ze trida ma zavislost na jine sluzbe
- ForestCZE
- Člen | 209
Mysteria napsal(a):
Nechtěl jsi spíš napsat něco takovéhleho?
namespace App\Model; use Nette\Database\Context; class Rating { /** @var Context */ private $database; public function __construct(Context $database) { $this->database = $database; } public function updateRating() { $this->database->table('rates')->fetch(); } }
A do config.neon do services přidej
App\Model\Rating
.A v presenteru pak budeš mít
/** @var Rating @inject */ public $rating; $this->rating->updateRating();
Všimni si že nikde není použito ani jedno new, takže nemusíš řešit, co předávat do connection za parametry a podobně. O všechno se za tebe postará DI.
Vůbec jsem si tvého příspěvku nevšiml a nakonec jsem to tak udělal. Moc děkuju :)
- Jan Mikeš
- Člen | 771
CZechBoY napsal(a):
Uplne vsechno :-)
Treba nekdy v budoucnu budes chtit pridat dalsi zavislost pro tridu Rating. Jelikoz uz budes mit na 50 mistech v kodu napsanynew Rating($connection)
tak to bude docela zabava na dlouhou noc. Pokud bys ale mel sluzbu a pouzival tu tridu jako sluzbu tak bys zmenil jen konstruktor (pripadne smazal cache) a je hotovo.ps. indikatorem ze by trida mela byt sluzbou mi je to, ze trida ma zavislost na jine sluzbe
Ne tak docela. Rating
služba být nemusí, můžeš si
vytvořit RatingFactory
, která bude tvůj rating vytvářet, a
tuto továrnu zaregistruješ jako službu.
class RatingFactory
{
private $database;
public function __construct(Context $database)
{
$this->database = $database;
}
public function create(): Rating
{
return new Rating($this->database);
}
}
Použití v presenteru by pak vypadalo takto:
class Presenter
{
/** @var RatingFactory @inject */
public $ratingFactory;
public function renderDefault()
{
$rating = $this->ratingFactory->create();
}
}
Avšak v tomto případě to nedává smysl, protože třída
Rating
by opravdu měla být službou, uvádím to tedy pro
úplnost řešení a odpověď na otázku
Vycházel jsem z toho, že nechci, aby Rating byla služba a chtěl jsem jenom poradit
.
Editoval Jan Mikeš (1. 11. 2017 0:37)