Service not found při deklarování v config.neon
- Bogi
- Člen | 24
Zdravíčko! Snažím se učit Nette a zadrhnul jsem se u následujícího problému:
Chci si vytvořit službu (vlastní připojení k databázi) v config.neon, kde mám mimo jiné toto:
parameters:
database:
host: localhost
dbname: test
username: admin
password: heslo
services:
db: App\Model\DBConnection(%database%)
Tím chci vytvořit tuto službu (připojení k databázi):
namespace App\Model;
class DBConnection
{
private $host;
private $username;
private $password;
private $dbname;
private $connection;
function __construct(array $params)
{
$this->host = $params['host'];
$this->username = $params['username'];
$this->password = $params['password'];
$this->dbname = $params['dbname'];
$mysqli = new \mysqli($this->host, $this->username, $this->password, $this->dbname);
if ($mysqli->connect_error) {
throw new \Exception($mysqli->connect_error);
}
$mysqli->set_charset('utf8');
$this->connection = $mysqli;
}
public function query($query)
{
if (!$result = $this->connection->query($query)) {
throw new \Exception($this->connection->error);
}
return $result;
}
}
A nakonec bych rád tuto službu předal jako parametr jiné službě (manažeru uživatelů), ale nejde to:
<?php
namespace App\Model;
use Nette,
App\Model;
class MyDI extends Nette\DI\Container {
protected function createServiceUserManager()
{
return new Model\UserManager($this->getService('db'));
}
}
Stále totiž dostávám tuto chybu:
Nette\DI\MissingServiceException
Service ‚db‘ not found.
na řádku kodu:
return new Model\UserManager($this->getService('db'));
Může mi prosím někdo poradit, co dělám špatně?
- Martk
- Člen | 661
Systemový container (ten co jsi ručně vytvořil MyDI a můžeš ho smazat) se generuje sám v závislosti na nastavení konfiguračních souborů (neon) nebo rozšíření.
Když dopíšeš do neonu:
parameters:
database:
host: localhost
dbname: test
username: admin
password: heslo
services:
db: App\Model\DBConnection(%database%)
- Model\UserManager(@db)
- Model\UserManager(@App\Model\DBConnection) # nebo
Tak se tato služba (Model\UserManager) vygeneruje do containeru a předá jí službu App\Model\DBConnection.
Nette je chytré a pokud v konstruktoru používáš type hinting tříd, můžeš si ušetřit psaní a zvednout úroveň.
Neon:
parameters:
database:
host: localhost
dbname: test
username: admin
password: heslo
services:
db: App\Model\DBConnection(%database%)
- Model\UserManager
UserManager
namespace Model;
class UserManager {
/** @var \App\Model\DBConnection */
private $db;
public function __construct(\App\Model\DBConnection $db) {
$this->db = $db;
}
}
PS: jak vypadá tvůj současný generovaný systemový kontainer najdeš v temp/cache/Nette.Configurator
- Bogi
- Člen | 24
Díky moc za odpověď, hodně mi pomohla! :)
Z dokumentace jsem to pochopil, že si musím pro služby vytvořit vlastní DI kontejner, což jsem samozřejmě pochopil špatně, protože v mnou vytvořeném DI kontejneru nemám žádné služby. Proto mi to psalo, že služba neexistuje.
Už mi svět zase dává smysl! :D