Service not found při deklarování v config.neon

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
Bogi
Člen | 24
+
0
-

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
+
+5
-

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

chemix
Nette Core | 1310
+
+10
-

Druha rada, nepis si vlastni databazovy cokoli, sahni bud po nette database, nebo dibi, nebo nejake orm at uz doctrine nebo nextras orm. Timhle akorat ztracis cas :-) overeno za tebe ;-)

Bogi
Člen | 24
+
0
-

Díky moc za odpověď, hodně mi pomohla! :)

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

Bogi
Člen | 24
+
0
-

Díky za radu, určitě se tím budu řídit a začnu používat nejspíš dibi, až se to trochu naučím. :)
Zatím se snažím pochopit, jak vlastně DI a služby fungují, tak si zatím zkouším takové jednoduchoučké příklady na vytváření služeb, abych to na tom pochopil…