Jak injectovat statickou laděnku?

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

Občas mám kus kódu, kde potřebuji natrvalo (tj. ne jen pro dočasný debugging) využít laděnky.

Typický příklad je JSON API, kde odchytávám obecnou Exception, která by jinak vylítla až do ErrorPresenteru a vykreslila tak HTML error na JSON API, což je z principu nežádoucí.

Když tímto způsobem zakrývám ErrorPresenter, nechci zahazovat všechny exceptions, které tam nastanou, chci je dál logovat.

try {
    // do something useful
} catch( \Exception $e ) {
    Debugger::log( $e );
    $this->draw_500_json_response();
}

Protože kód chci mít patřičně otestovaný a být schopen cokoliv předat jako mock, důkladně využívám DI.

Laděnku ovšem skrz DI jde předat dost blbě a ještě hůř namockovat její statické metody.

Ano, mohl bych si vyrobit něco jako ErrorJsonPresenter a nechat to probublat až tam, ale často prostě chci danou exception ošetřit lokálně (co když třeba v tom API chci zpátky v response přdat nějaké parametry navíc a nechci aby to bublalo k nějaké obecné JSON 500?).

Z praktického (= lenivého) hlediska bych teoreticky chápal, proč jsou všechny metody statické, ale z výše uvedeného důvodu mi dává větší smysl je statické nemít.

Máte někdo na tento problém řešení / nějaký lepší důvod, proč laděnka žije stále se statickými metodami?

Editoval maarlin (26. 8. 2012 22:19)

Filip Procházka
Moderator | 4668
+
0
-

Udělej si třídu logger, kterou zaregistruješ do DIC a která bude tajně pracovat s laděnkou :)

maarlin
Člen | 207
+
0
-

HosipLan napsal(a):

Udělej si třídu logger, kterou zaregistruješ do DIC a která bude tajně pracovat s laděnkou :)

Taky mě to napadlo, ale spíš hledám nějaký hlubší důvod, proč je laděnka stále statická, než abych se to snažil bezdůvodně obcházet.

Filip Procházka
Moderator | 4668
+
0
-

Protože není důvod aby nebyla statická? Laděnku není důvod mockovat, ani vytvářet několik instancí, protože nemáš šanci vytvořit několik oddělených prostředí, kde by se každé chovalo jinak.

paranoiq
Člen | 392
+
0
-

já bych velmi uvítal, kdyby laděnka byla skutečně objektová a dostupná jako klasická konfigurovatelná služba (minimálně ty služby jako bluescreen nebo logger). tohle se skoro nedá upravovat. statické rozhraní pro zjednodušení může být i tak (podobně jak je to u Dibi)

Filip Procházka
Moderator | 4668
+
0
-

Bluescreen, Bar a Logger by skutečně služby být mohly, to zní rozumně. Ale nesouhlasím s tím, že se špatně konfigurují.

Panda
Člen | 569
+
0
-

Já osobně nevidím moc důvod, proč by laděnka měla být objektová. Tím, jak moc ovlivňuje vykonávání skriptu na globální úrovni, mi vůbec do konceptu DI a služeb nepasuje. Něco, co při své inicializaci nastavuje error_reporting, přidává globální konstanty kvůli kompatibilitě, volá register_shutdown_function, set_exception_handler, set_error_handler a další věci, by podle mě opravdu nemělo být jako objektová služba – operuje globálně a rozhodně nepůjde izolovat do objektu. Navíc je nutné laděnku inicializovat ještě před tím, než se skript o nějakých službách dozví, čímž se opět z konceptu služeb vymaňuje.

Osobně bych volil řešení, které je zmíněno hned ze začátku: laděnku ponechat statickou a připravit nějaké rozumné mockovatelné rozhraní a adaptér, který bude některé funkce laděnky zpřístupňovat.

Editoval Panda (27. 8. 2012 15:29)

maarlin
Člen | 207
+
0
-

Panda napsal(a):

Osobně bych volil řešení, které je zmíněno hned ze začátku: laděnku ponechat statickou a připravit nějaké rozumné mockovatelné rozhraní a adaptér, který bude některé funkce laděnky zpřístupňovat.

V tom vidím docela dobré řešení a dává mi to smysl.