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 XxxServicenedě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)