Injektování aktuálního presenteru do service

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

Ahoj,

zkouším, co se dá udělat s novým Nette (jedu 2.0 (revision 013c8ee released on 2012–02–03) ). Zajímá mě, jestli když mám např. takovouhle konfiguraci:

config.neon

common:
    # ...

    services:
        # ...
        auditlogService:
            class: AuditlogService

a chtěl bych do služby auditlogService dostat aktuální presenter, tedy ten, který se zrovna vykonává. Může se jednat např. o to, že chci mít v této logovací službě vždy k dispozici httpRequest (loguji url, ip), můžu z toho brát aktuálního uživatele atd. Pochopitelně bych si to mohl nasetovat ručně někde při spuštění BasePresenteru, ale pokud mám takových služeb víc, tak to značně znepřehledňuje.

Lze tohle nějak rozumně udělat?

ŘEŠENÍ

AuditlogService.php

class AuditlogService extends NObject {
    /**
     * @var NPresenter
     */
    private $presenter;

    /**
     * @param NApplication $application
     */
    function __construct($application) {
        $this->presenter = $application->getPresenter();
    }
    // ...
}

config.neon

common:
    services:
        auditlogService:
            class: AuditlogService
            arguments: [@application]

Editoval Savannah (9. 2. 2012 21:19)

mkoubik
Člen | 728
+
0
-

To by ti mělo stačit si injectnout ten httpService, na to stačí:

services:
	auditlogService:
		class: AuditlogService(@httpRequest) // nebo jak se ta služba jmenuje

(píšu to z hlavy).

Savannah
Člen | 30
+
0
-

No já toho právě chci obecně víc než jenom ten httpRequest. Chci uživatele, můžu někdy chtít presenter abych měl metodu $presenter->link atd. Prostě by se mi hodil presenter jako celek. Zkoušel jsem něco jako

services:
    auditlogService:
        class: AuditlogService
        arguments: [@presenter] # popř. @currentPresenter

ale ty @presenter/@currentPresenter neexistují.

mcmatak
Člen | 499
+
0
-

Vždyť každy servis musí mít vztah ke context a skrz něho se dostanete na aktualni presenter ne?

Ale hlavně mi to přijde divny požadavek podle mne je něco spatne

mkoubik
Člen | 728
+
0
-

Vždyť každy servis musí mít vztah ke context a skrz něho se dostanete na aktualni presenter ne?

Služba může být jakýkoliv objekt, tudíž nemůžeme předpokládat že ví o nějakém contextu, natož presenteru.
>

Ale hlavně mi to přijde divny požadavek podle mne je něco spatne

Přesně tak, presenter by měl mít referenci na modely, ne obráceně. Skus promyslet, jestli by to nešlo zpracovat v presenteru a do modelu pak posílat jenom data.

David Grudl
Nette Core | 8147
+
0
-

Můžeš si předat @application a ten má metodu getPresenter().

Savannah
Člen | 30
+
0
-

mkoubik napsal(a):

Ale hlavně mi to přijde divny požadavek podle mne je něco spatne

Přesně tak, presenter by měl mít referenci na modely, ne obráceně. Skus promyslet, jestli by to nešlo zpracovat v presenteru a do modelu pak posílat jenom data.

Takhle to dělám, ale je zbytečně složité do každé metody posílat jako první parametr $this, případně ve startupu každého presenteru projít všechny services, které potřebují referenci, a nastavit ji.

David Grudl napsal(a):

Můžeš si předat @application a ten má metodu getPresenter().

To by mělo být to, co potřebuji! :) Dík, jen co dorazím domu, vyzkouším

mcmatak
Člen | 499
+
0
-

Já teda vytvářím service vždy s prvním parametrem konstruktoru což je context

Savannah
Člen | 30
+
0
-

mcmatak napsal(a):

Já teda vytvářím service vždy s prvním parametrem konstruktoru což je context

Jak to myslíš konkrétně? Parametry konstruktoru totiž musím dávat přímo v config.neon (servicy mi nevytváří presenter, ty jsou do něj injectnuté). Což je to, čehož chci dosáhnout – přímo v configu moct injectovat presenter (nebo context, nevím, jak je přesně rozdíl/vztah).

Což by mohlo řešit to Davidovo @application

Filip Procházka
Moderator | 4668
+
0
-

@**Savannah**: @**mcmatak** to myslí tak, že všechny jeho služby dostávají celý DI Container, čímž ho degradoval na Service Locator :) Což není pěkné.

Savannah
Člen | 30
+
0
-

Tak jsem zkusil Davidovu radu a funguje báječně! :)

class AuditlogService extends NObject {
    /**
     * @param NApplication $application
     */
    function __construct($application) {
        $this->presenter = $application->getPresenter();
    }
    // ...
}
common:
    services:
        auditlogService:
            class: AuditlogService
            arguments: [@application]

Takhle dostanu do auditlogService aktuální presenter a mám tedy přístup ke všemu, co potřebuji (httprequest, user, parameters, …). Díky!