- norbe
- Backer | 405
Ahoj,
právě předělávám firemní systém a jelikož chci
jít s dobou
, snažím se minimalizovat výskyt volání
Environment
.
Implementoval jsem si upravený DI podle Honzi Marka, ale co nevím jakým
způsobem nahradit je získání cache –
Environment::getCache("foo")
. Má to vůbec smysl? Filestorage se
dá nahradit pomocí konfigu, takže při testování by problém taky být
neměl, nebo se pletu?
- Filip Procházka
- Moderator | 4668
Ahoj, právě jsem dokončil (snad) refaktoring Patrikového DI a mělo by to fungovat ok. Mám to trochu více rozdělené a připojuji to do systému pomocí vlastního konfigurátoru
Když si prohlédneš https://github.com/…actories.php tak třeba i pochopíš jak se to používá a jak jdou určité věci spojovat a nahrazovat :)
- norbe
- Backer | 405
Ono se to co do použití moc neliší od toho co má Honza, naopak mi
přijde lepší jeho konfigurace skrz konfigurák. Co jsem ale nepochopil ani
z těch tvých zdrojáků je jak nahradit zmiňovaný kód
Environment::getCache("foo")
. To bych měl pro každý namespace
keše vytvářet novou konfiguraci, kde akorát změním parametr konstruktoru?
To mi nepřijde jako nejlepší řešení… Proto se zeptám ještě
jednou:
Má to vůbec smysl? Filestorage si můžu nastavit v konfigu. Co je tedy špatného na použití Environment::getCache(„foo“)? Jaké konkrétní problémy mi to může způsobit?
- Jan Tvrdík
- Nette guru | 2595
Čisté řešení (dle mě) pro náhradu
Environment::getCache("foo")
v presenteru je doplnit do
BasePresenteru
:
Jaké konkrétní problémy mi to může způsobit?
Nahrazování cache storage bude škaredé (tj. úpravou kontextu Env. místo úpravou kontextu presenteru).
- Filip Procházka
- Moderator | 4668
Ale samozřejmě, že to jde nastavit v configu… Tohle jsou jenom rozepsané a více nakonfigurované výchozí služby a ukazují možnosti konfigurace.
Funguje to tak, že se
- vymění výchozí Configurator za nový
- v momentě načtení
configu (
Environment::loadConfig()
) se automaticky vytváří ServiceContainer - tento ServiceContainer je naplněn hodnotami z Configu a zároveň jsou mu upraveny služby, aby odpovídaly nastavení z configu
- služby, které se mají spustit hned (
run: TRUE
) tak se spustí a ServiceContainer nyní obsahuje všechny služby a všechny data z Configu (odpadá potřeba volat Environmeng::getVariable())
Do jakékoliv služby předám tak přesně co potřebuji včetně jiných libovolných zaregistrovaných služeb, což mi docela zásadně rozšiřuje možnosti jak „surové konfigurace“ pomocí nastavení jako je třeba to memcache v odkazu, tak i možnosti parametrů předané továrničce. Viz vytváření EntityManageru.
Navíc moje implementace má pár vychytávek navíc.
- Pokud služba implementuje
IContainerAware
je jíServiceContainer
předán automaticky. - Je možné nadefinovat alias (
aliases: ['memcache']
) a pak k té službě přes něj přistupovat, třeba v presenteru$this->getServiceContainer()->memcache
,$this->getServiceContainer()->httpRequest
, … - Patrikova implementace dovoluje ke službám (a aliasům) přistupovat přes
ArrayAccess, já se
rozhodl, že přes
ArrayAcces
budou přístupné (stejně jako přesServiceContainer::getParameter($key)
) konfigurační direktivy. Lze proto volat$this->serviceContainer['database']; // database z configu
. - V konfiguraci argumentů továrniček, tříd a metod mám navic
syntaktickou třešničku a je možné předávat rovnou prvky pole
array('%database[host]%', '%database[username]%', '%database[password]%')
, počítá se ale pouze s jedním zanořením (%neco[neco][neco]%
vyhodi chybu)
Editoval HosipLan (17. 3. 2011 21:39)
- Jan Tvrdík
- Nette guru | 2595
Zdá se mi to, nebo jsi pořád neodpověděl na otázku, jak nahradit
Environment::getCache("foo")
? :o)
- Filip Procházka
- Moderator | 4668
Máš pravdu neodpověděl jsem přímo, jenom jsem ukázal jaké jsou možnosti :)
Co třeba nastavit službu, aby přijímala ICacheStorage
?
nastavení
služba
v případě presenteru je to velice podobné, tam by se dal i udělat
helper, který by jako v environment vracel vždy jinou instanci třídy
Nette\Caching\Cache
podle argumentu.
Editoval HosipLan (17. 3. 2011 21:41)
- Jan Tvrdík
- Nette guru | 2595
Díky za praktickou ukázku, vypadá to pěkně. Těším se, až se něco takového dostane do Nette.
- Patrik Votoček
- Člen | 2221
Jan Tvrdík napsal(a):
Čisté řešení (dle mě) pro náhradu
Environment::getCache("foo")
v presenteru je doplnit doBasePresenteru
:
Posledních pár dní pracuju s cache pomocí DI a začalo mě extrémně
vadit že Nette\Caching\Cache
nemá setter pro nastavení
namespace. A tak jsem se nad tím zamyslel hlouběji a zkoumal jsem jak na to
až jsem došel k tomu že lepší řešení než to co jsi napsal nevymyslím
(došel jsem ke stejnému).
Takže ve výsledku je odpověď taková že se injektuje Storage a instancuje se „ručně“.
- norbe
- Backer | 405
Díky za tipy, hnedka to vypadá líp než nastavovat speciální službu pro každé použití cache. Po pravdě jsem se k obdobnému řešení dopracoval i po zkouknutí pár tříd v nette, ale přišlo mi to trochu proti principu DI vytvářet na pevno instanci nějaké třídy. Asi to bude chtít trochu citu, co ještě posílat konstruktorem/setterem a co už vytvářet na pevno v dané třídě.
- Patrik Votoček
- Člen | 2221
Tak teoreticky by šlo udělat i:
a jako službu používat MyCache
místo
Nette\Caching\Cache
.
- Jan Tvrdík
- Nette guru | 2595
norbe wrote:
přišlo mi to trochu proti principu DI vytvářet na pevno instanci nějaké třídy
Ty používáš DI jen ze srandy nebo aby si byl cool? Já používám DI, aby se kód snáze testoval, a to mnou navržené řešení bez problému splňuje. Nedává smysl používat DI jen tak pro nic za nic.
Co ještě posílat konstruktorem/setterem a co už vytvářet na pevno v dané třídě.
Nechápu, musel bys mi poslat ukázku.
Patrik Votoček wrote: Tak teoreticky by šlo udělat i (…)
To se mi nelíbí.
OT: Nechce někdo Davidovi poslat úpravu stylu pro citace? Ty současné jsou strašně nafouklé.
- norbe
- Backer | 405
No rozhodně to nedělám jen abych si zkrátil dlouhou chvíli, ale právě proto, že mně čeká poměrně dost úprav, tak chci aby to bylo udělané pořádně. Mimo jiné taky konečně začínám s psaním testů a proto si potřebuju ujasnit nějaké základní principy.
Nechápu, musel bys mi poslat ukázku.
To právě souviselo s tím příkladem s cachí. Jakože si člověk musí získat trochu citu pro to, co mu tam při testech může dělat problém, což se mně jako někomu kdo s tím teprve začíná určuje blbě.
Editoval norbe (18. 3. 2011 10:59)
- Jan Tvrdík
- Nette guru | 2595
Tak v testech jde o to nahradit závislosti a toho konkrétně v případě presenteru můžeš dosáhnout dvěma způsoby (bez toho, abys to složitě mockoval):
- předáš mu upravený kontext (DI princip)
- vytvoříš si potomka, který překryje třeba právě tu metodu
getCache
.
- Filip Procházka
- Moderator | 4668
- A u služby, která nevyžaduje celý
Context
jí předáš jenomICacheStorage
:)
Editoval HosipLan (18. 3. 2011 11:29)
- Filip Procházka
- Moderator | 4668
přesně takhle https://forum.nette.org/…e-foo-z-kodu#…,
jenom to nebude @Nette\Caching\ICacheStorage
ale @cacheStorage
Editoval HosipLan (20. 5. 2011 11:05)