Jak vytvořit události, aby se volaly vždy? Problém s lazy vytvářením služeb

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

Zdravím,
zkouším eventy v Nette a narazil jsem hned na problém, kdy se mi nevytváří služby (lazy load) a tak nedojde k přihlášení odběru události.

Krátká ukázka nic nezkazí:

class Event extends Nette\Object
{
	public $onFired = [];

	public function fire()
	{
		$this->onFired();
	}
}
class Subscriber extends Nette\Object
{
	public function __construct(Event $event)
	{
		$event->onFired[] = function () {
			barDump('fired');
		};
	}
}
class EventPresenter extends Presenter
{
	/** @var Event @inject */
	public $event;

	public function actionDefault()
	{
		$this->event->fire();
	}
}

Služba Subscriber se samozřejmě nevytvoří, protože se nikde nepoužívá.
Jak tohle řešíte?
Existuje jiná možnost než tagování ala Kdyby\Events?

Editoval CZechBoY (30. 5. 2016 12:45)

Felix
Nette Core | 1186
+
0
-

Delal jsem si sve vlastni eventy. Muzes mrknout na Minetro/Events.


Princip je takovy, ze aby jsi mel lazy-loading a zaroven se ti ty sluzby registrovali. Tak musis pres CompilerExtension, vytahnout vsechny sluzby s prislusnym tagem (napriklad). Pripadne, ty ktere implementuji nejaky typ. A ziskat z nich na jaky event reaguji, potom uz lazy-loading funguje v pohode.

Pokud bys chtel uplne nejjednodussi reseni. Tak si pridej k tem subsriberum tag run.

CZechBoY
Člen | 3608
+
0
-

Ideální by pro mě bylo, kdybych nemusel dělat nic (protože když musim něco dělat explicitně tak na to zapomenu :-) …) – tzn. šlo by nějak zjistit, které služby mají jako závislost Event? Potom tyhle služby vytvořit (zavolat konstruktor+inject případně).
Je mi jasný, že třeba setup by se blbě zjišťoval jako závislost.

Editoval CZechBoY (30. 5. 2016 12:59)

Felix
Nette Core | 1186
+
0
-

To urcite muzes. Napis si EventsExtension.

public function beforeCompile()
{
    $container = $this->getContainerBuilder();
    foreach ($container->findByType('App\Model\Events') as $name => $subscriber) {
        $subscriber->addTag('run');
    }
}

Projde vsechny sluzby a ktere jsou typu App\Model\Events, tak jim prida run tag.

Editoval Felix (30. 5. 2016 17:30)

CZechBoY
Člen | 3608
+
0
-

@Felix To se mi nezdá… ten kod najde jen službyurčitýho typu a ne služby, který maj jako závislost (konstruktor/inject/setup) App\Model\Events.

Hádám, že nejde ovlivnit kod, který vygeneruje kompilátor? Takže bych musel mít vlastní cache pro parsování typehintů u metod/property v rozšíření dic :-/

Felix
Nette Core | 1186
+
0
-

CZechBoY napsal(a):

@Felix To se mi nezdá… ten kod najde jen službyurčitýho typu a ne služby, který maj jako závislost (konstruktor/inject/setup) App\Model\Events.

Hádám, že nejde ovlivnit kod, který vygeneruje kompilátor? Takže bych musel mít vlastní cache pro parsování typehintů u metod/property v rozšíření dic :-/

No, snazim se ti nejak pomoc a nasmerovat.. Ale jestli se ti to nezda, tak to bohuzel nemuzu slouzit. :-)

CZechBoY
Člen | 3608
+
0
-

Jj, tyhle moznosti znam.. Jen by se mi libilo, kdybych u listeneru nemusel nejak explicitne uvadet, ze odebiram nejaky udalosti (+ jeste vyjmenovat jaky).