Volání getService v Nette 2.1

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

Ahoj,
zkouším nasadit Nette 2.1 a je tam deprecated volání $this->getService('name'). Má být nahrazen $container->getService('name'). Jak do presenteru dostanu ten $container? zatím to volám přes context, ale to se mi nezdá, že by bylo správné řešení: $this->presenter->context->getService(‚name‘))`.

S containerem se v pracuje v dokumentaci konfigurace, ale tam se vytváří nový kontainer, který bude prázdný a nebude to ten systémový, který já chci. Nebo se pletu?

Díky

ViPEr*CZ*
Člen | 817
+
0
-

Použijte inject* metodu. https://pla.nette.org/…ect-autowire

Oli
Člen | 1215
+
0
-

Díky, tohle už používám na třídy, který si vytvořím. Problém je, že nevím co mám injectnout, když chci do presenteru dostat z configu @cacheStorage. Do jiný třídy to dostanu settingsModel: SettingsModel(@cacheStorage), jak to ale dostanu do presenteru?

Nebo jak jinak si tahat storage z configu? Tohle mě doteď fungovalo dobře.

peter.z
Člen | 37
+
0
-

Takto:

private $cacheStorage;

public function injectCacheStorage(\Nette\Caching\IStorage $cacheStorage)
{
	$this->cacheStorage = $cacheStorage;
}

Pripadne ten interface Nette\Caching\IStorage mozes nahradit konkretnou triedou ak pouzivas vlastny cache storage alebo ich mas nadefinovanych viac ako 1 v configu :)

Oli
Člen | 1215
+
0
-

Super, to funguje. Díky! Já už jsem to teda takhle zkoušel, ale nedošlo mě, že zpracování musím hodit jinam. Jsem v jednom injectu volal jiný inject.

Když už se ptám na tahání z configu, jak se správně tahají parametry? Já to znám jen přes $this->context->param['jmeno'].

peter.z
Člen | 37
+
0
-

Myslim si, ze v presenteroch je to asi jedina cesta (nech ma niekto opravi, ci je to aj v dev verzii), ale v services si mozes tie parametre vlozit do constructoru, napr.:

Konfiguracia:

services:
	example: Example(%exampleParams%)

parameters:
	exampleParams:
		sk: Priklad
		en: Example

Trieda / service:

class Example
{
	private $params = array();

	public function __construct(array $params) // Tu ti Nette vlozi vsetko co je v exampleParams v configu
	{
		$this->params = $params;
	}
}
hAssassin
Člen | 293
+
0
-

@Oli > no melo by to jit pres tovarnicku. A to zhruba tak, ze si vytvoris jednoduchou tridu, pres konstruktor injection si ji predas parametry, ktery potrebujes a v konfigu ji registrujes jako sluzbu. A tu si pak injektes do presenteru. Cili vicmene tak jak psal peter.z vyse, takorat si tu tridu Example injektnes do presenteru.

Oli
Člen | 1215
+
0
-

Díky.
V podstatě stejně jsem to zkoušel, ale mám s tím problém. Když to takhle uvedu v configu, tak mě to potom hází chybu. On teda není problém ani tak s tím parametrem, ale s tím co dál chci v constructoru. Abych to teda uvedl celý. Možná to dělám uplně blbě a dělá se to jinak, nicméně mám to takhle:

BasePresenter:

protected function startup()
{
	parent::startup();
	$cache = new Nette\Caching\Cache($this->cacheStorage, 'appSettings');

	$settings = new CachedSettingsRepository($this->settingsModel, $cache);
	// nebo (tady nevím) - oboje nefunguje
	$settings = $this->cachedSettingsRepository($this->settingsModel, $cache);

	$this->settings = $settings->find();
}

public function injectCacheStorage(\Nette\Caching\IStorage $cacheStorage)
{
	$this->cacheStorage = $cacheStorage;
}

public function injectSettings(\SettingsModel $settingsModel)
{
	$this->settingsModel = $settingsModel;
}

// ??????
public function injectCachedSettingsRepository(\CachedSettingsRepository $repository)
{
	$this->cachedSettingsRepository = $repository;
}

CachedSettingsRepository:

class CachedSettingsRepository extends Nette\Object implements ISettingsRepository
{
	/** @var UsersRepository */
	public $repository;

	/** @var Nette\Caching\Cache */
	private $cache;

	private $params = array();

	public function __construct(array $params, SettingsModel $repository, Nette\Caching\Cache $cache)
	{
		$this->repository = $repository;
		$this->cache = $cache;
		$this->params = $params;
	}

	/**
	* @param integer $id
	* @return User
	*/
	public function find()
	{
		$self = $this;
		$value = $this->cache->load($this->params['variantSettings'], function($self) use ($self) {
			$value = $self->repository->getRows($self->params['variantSettings']);
			return $value;
		});
		return $value;
		// Tady taky nevím co je lepší. Ta funkce dole mě přijde, že to neuložilo do cache, protoze se porad volala db
//		return $this->cache->call(callback($this->repository, 'getRows'), $this->params['variantSettings']);
	}
}

config.neon:

common:
	parameters:
		param:
			variantSettings: 1
services:
	cachedSettingsRepository: CachedSettingsRepository(%param%)

Takhle si myslím, že by mě to mělo fungovat (mám pocit, že takhle nějak už mě to funguje jinde), ale hází mě to výjimku:

`Nette\DI\ServiceCreationException

Service ‚cachedSettingsRepository‘: No service of type Nette\Caching\Cache found. Make sure the type hint in CachedSettingsRepository::__construct() is written correctly and service of this type is registered.`

Jestli to chápu dobře, tak je jasný, že to nenajde tu cache. Tu chci naplnit až později, až ve startupu…

Je to teda vubec takhle správný přístup?

David Matějka
Moderator | 6445
+
0
-

mas k tomu nejaky duvod, abys cache nastavoval az v presenteru?

nejlepsi by bylo v tom CachedSettingsRepository mit takovej konstruktor:

public function __construct(array $params, SettingsModel $repository, Nette\Caching\IStorage $cacheStorage)
    {
        $this->repository = $repository;
        $this->cache = new Nette\Caching\Cache($cacheStorage, 'appSettings');
        $this->params = $params;
    }
peter.z
Člen | 37
+
0
-

Obavam sa, ze tu cache budes musiet vytvarat v tom CachedSettingsRepository. Skus toto:

class CachedSettingsRepository extends Nette\Object implements ISettingsRepository
{
    /** @var UsersRepository */
    public $repository;

    /** @var Nette\Caching\Cache */
    private $cache;

    private $params = array();

    public function __construct(array $params, SettingsModel $repository, Nette\Caching\IStorage $storage)
    {
        $this->repository = $repository;
        $this->params = $params;
        $this->cache = new Nette\Caching\Cache($storage, 'appSettings');
    }

    /**
    * @param integer $id
    * @return User
    */
    public function find()
    {
        $self = $this;
        $value = $this->cache->load($this->params['variantSettings'], function() use ($self) {
            $value = $self->repository->getRows($self->params['variantSettings']);
            return $value;
        });
        return $value;
        // Tady taky nevím co je lepší. Ta funkce dole mě přijde, že to neuložilo do cache, protoze se porad volala db
//      return $this->cache->call(callback($this->repository, 'getRows'), $this->params['variantSettings']);
    }
}

A samotny presenter:

protected function startup()
{
    parent::startup();

    $settings = $this->cachedSettingsRepository;

    $this->settings = $settings->find();
}

// Toto nechas ako je
public function injectCachedSettingsRepository(\CachedSettingsRepository $repository)
{
    $this->cachedSettingsRepository = $repository;
}

Tie zvysne dva injecty som odtial zmazal.. Ak ich ale budes potrebovat aj niekde inde v presenteri, tak ich tam ponechaj, inac su tam pre CachedSettingsRepository zbytocne, pretoze ten ich ziska v __construct od kontajnera.

Oli
Člen | 1215
+
0
-

Díky, tohle funguje