Volání getService v Nette 2.1
- Oli
- Člen | 1215
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
- Oli
- Člen | 1215
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
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 :)
- peter.z
- Člen | 37
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
@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
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
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
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.