Vytvoření služby, která má přístup ke všem definovaným službám?

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

Dobrý den,

potřeboval bych si vytvořit službu, která bude mít přístup ke všem definovaným službám aplikace. A pokud bude nějaká služba implementovat určité rozhraní, vytáhnout si zní potřebná data.

Jaká závislost je třeba předat, abych k tomu měl přístup?

Editoval jEhLa (9. 9. 2014 11:15)

David Matějka
Moderator | 6445
+
0
-

musel bys vyzadovat Nette\DI\Container. Ale radeji napis konkretni problem, co resis, treba najdem lepsi reseni :)

jEhLa
Člen | 70
+
0
-

Chci vytvořit službu, která bude shromažďovat upozornění z ostatních služeb. Například BlogModel bude vracet upozornění že je zde stále nějaký nepublikovaný článek. EshopModel bude vracet že nějaký produkt již není na skladě apod. Další modely jsou v aplikaci však přidávány za chodu z extension. Takže vyžadování závislostí na konkrétní modely není možné. Proto mi přišlo lepši si vyžádat všechny služby, projít si je, a vrátit jen ty implementující rozhraní pro upozornění.

David Matějka
Moderator | 6445
+
+4
-

Mozna, ze kdyby/events je to, co hledas..

mkoubik
Člen | 728
+
0
-

Tam ale asi narazíš na problém který jsem nedávno řešil já. Asi bych si do těch služeb předal rovnou event manager a volal na něm dispatchEvent() ručně.

jEhLa
Člen | 70
+
0
-

Díky za rady, asi by se to tím dalo také vyřešit. Ale přijde mi to zbytečně mohutný nástroj na takovou drobnost.
Potřebuji prostě jen na jedné stránce udělat souhrn aktuálních informací ze všech modelů.

Přes ten Nette\DI\Container by to taky nějak mělo jít ne? V dumpu tyto služby sice vidím, ale vše je zde private, nebo protected. Jak se k tomu dá dostat?

Michal Vyšinský
Člen | 608
+
0
-

Zavolej $container->findByType(‚Pozadovany\Interface‘) a dostaneš služby implementující daný interface.

Editoval Michal Vyšinský (9. 9. 2014 12:03)

David Matějka
Moderator | 6445
+
0
-

@mkoubik to by mozna (nezkousel jsem) melo resit tohle

@jEhLa tak si udelej sluzbu, treba InformationCollector, a vsechny InformationProvider registruj jako sluzbu, dej ji tag a v compiler extension beforeCompile si ziskej vsechny sluzby s tim tagem a predej je information collectoru

David Kudera
Člen | 455
+
0
-

Michal Vyšinský napsal(a):

Zavolej $container->findByType(‚Pozadovany\Interface‘) a dostaneš služby implementující daný interface.

Pokud se nepletu, tak tím jen získá pole názvů registrovaných služeb, takže pak ještě

$container->getService($name);
Michal Vyšinský
Člen | 608
+
0
-

David Kudera napsal(a):

Michal Vyšinský napsal(a):

Zavolej $container->findByType(‚Pozadovany\Interface‘) a dostaneš služby implementující daný interface.

Pokud se nepletu, tak tím jen získá pole názvů registrovaných služeb, takže pak ještě

$container->getService($name);

Jj, pravda.

jEhLa
Člen | 70
+
0
-

@matej21 To bylo první co mě napadlo, protože vím že v CompilerExtension se k tomu dá dostat jednoduše. Ale přišlo mi divné toto dělat jako extension, když je to spíš jen služba.

@MichalVyšinský @DavidKudera Přesně to jsem potřeboval.

class NoticeProvider
{
	public function __construct ( \Nette\DI\Container $container ) {
		$noticeServices = $container->findByType('App\INoticeProvider');

		foreach ($noticeServices as $service){
			$service = $container->getService($service);
			\Tracy\Debugger::barDump($service->getNotices());
		}
	}
}

Díky za rady.

mkoubik
Člen | 728
+
0
-

@matej21 tam vidím dva zádrhele:

  • aby ta služba vůbec něco logovala, tak by sis musel vyžádat její instanci a zavolat na ní metodu (nefunguje push z té konkrétní služby)
  • pokud bys to udělal, tak by se zinstanciovaly všechny ty služby které má jako závislosti aniž by byly nutně potřeba
David Matějka
Moderator | 6445
+
0
-

@mkoubik imho @jEhLa nechce push (taky jsem to tak nejdrive pochopil), ale chce mit nejakou sluzbu, ktera posbira ze vsech INoticeProvider zpravy