Předání služby jiné službě

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

Zdravím, řeším teď jeden problém jak jedné sadě služeb předat jinou.

V config.neon mám zadefinované v části SERVICES služby které provádějí nějaké nastavování aplikace a jsou tam také fasády pro datové modely, zjednodušeně takto:

SERVICES:
	systemManager: \Core\SystemManaget

	clankyFacade: \Core\ClankyFacade
	kategorieFacade: \Core\KategorieFacade

Když se appka spustí tak v metodě startup zavolám v system manageru inizicalizaci která potřebuje nějaká data z URL, tam se provede spojení s DB a načtení vybrané entity se kterou se bude pak dále pracovat.

Co potřebuju vyřešit je jak tuto entitu pak dostat do jednotlivých fasád co pracují s databázi abych tam mohl udělat filtr podle toho jaký systém je právě načten.

Je možné to řešit tak že těm fasádovým službám injectuju tu službu přes neon? Budu mít pak k dispozici tu entitu v té injectované službě? Nebo je to řešení „na prasáka“?

Petr Hudík
Člen | 49
+
0
-

Zrovna jsem napsal toto řešení psal do jiného vlákna, tak možná uvažuji špatně, když ho nedokážu opustit, ale nepomohlo by tito toto?

Tedy konkrétně v Tvém případě, by šla inicializace převést do kontruktoru SystemManaget a do této třídy přidat funkci getDatabaseService, která vrátí Nette\Database\Connection. A v neposlední řadě můžeš vytvořit službu database, která se vytvoří pomocí továrničky SystemManaget::getDatabaseService, podobně jak jsem psal v odkazovaném vláknu.

akadlec
Člen | 1326
+
0
-

No já to možná napsal trochu chaoticky ;) zkusím lépe vysvětlit.

Mám službu systemManager a tato služba potřebuje ke správnce funkci parametr z url (na základě něj pak v sobě načte konkrétní záznam z DB který se dál v aplikaci využívá). Když sem to řešil „natvrdo“, tak jsem si ten parametr hodil do neonu a ten předal v inicializaci té služby, to bylo ok. Nicméně potřebuji to mít dynamické aby ten parametr byl získán z url, jenže jsem nepřišel na to jak tam dostat rozparsovanou url. Tak proto jsem to upravil tak, že v neonu se služba zaregistruje a pak v metodě startup v basepresenteru se pomocí $this->context->systemManager->register($param); tohle je zatím ok v té službě mám co potřebuji.

Problém je v tom že ten systémový manager, resp jeho část potřebuju mít v dalších službách co jsou použity pro databázový model.

Př.: představte si stránky idnes.cz, jsou tam nějaké články z každé oblasti, ale když dáte technet.idnes.cz tak se načtou jen články technetu. (toto je velké zobecnění) A něco takového tady řeším i já, prostě potřebuju mít v articlesFacade k dispozici ten systemManager kde pak můžu zavolat $systemManager->getSystem()->getId() což mi ze systémové manageru vytáhne entitu načteného systému a pak její ID a to ID dále použiju v podmínce pro načtení dat.

Jedno řešení je to že všude tam kde budu načítat data která jsou závislá na ID systému tu entitu či ID prostě předám jako parametr, což ale znamená X řádků na X místěch a tomu bych se rád vyhnul. A proto mě zajímá zda když udělám něco takového:

SERVICES:
    systemManager: \Core\SystemManaget

    clankyFacade:
	- class: \Core\ClankyFacade
	- injectSystemManager(@systemManager)
    kategorieFacade:
	- class: \Core\KategorieFacade
	- injectSystemManager(@systemManager)

za předpokladu že v těch fasádách bude metoda injectSystemManager, budu mít k dispozici stejný objekt jako je v tom startupu a zda je to korektní řešení.

A nebo existuje nějaká možnost jak dostat jednotlivé parametry routy do initu toho system manageru?

David Matějka
Moderator | 6445
+
0
-

tak prvni vec – jak dostat parametry do systemmanager.

muzes si jako zavislost do system manageru nechat poslat Nette\Application\Application, ktera ma udalost onRequest, ktera se vola, kdyz dojde k vytvoreni requestu na presenter (vetsinou je jen jeden – vracenej z routeru dle url, ale muze jich byt vic – interni presmerovani, errory atd.)

zhruba tedy takhle:

class SystemManager
{

	public function __construct(\Nette\Application\Application $application)
	{
		$application->onRequest[] = $this->processApplicationRequest;
	}

	public function processApplicationRequest(\Nette\Application\Applicatio $application, Nette\Application\Request $request)
	{
		$parameters = $request->getParameter();
		...
	}
}

v neonu dej potom systemmanageru tag run a tim se spusti pri inicializaci containeru

a druha vec, system manager do facad.

nejlepsi a nejjednodusi bude proste mit ve facadach zavislost na systemmanageru (nejlepe v konstruktoru)

akadlec
Člen | 1326
+
0
-

@matej21
díky za tip, určitě zkusím. Ad ty fasády, nad tím předat to v konstruktoru jsem už taky přemýšlel, výsledek ale bude ± stejný ne? jen s tím rozdílem že to nebude injectSystemManager($manager) ale __construct($manager)

David Matějka
Moderator | 6445
+
0
-

z funkcniho hlediska jo, ale uz se to tu parkrat resilo, ze nejlepsi je pradavat zavislosti pres konstruktor.

jinak nevim, na jakej verzi nette jedes, ale v dev verzi (a asi i od nejake 2.0.x, ale to bych kecal) umi DI container predavat zavislosti pres inject* metody automaticky. (samozrejme musis uvest typehint :))

akadlec
Člen | 1326
+
0
-

Jedu na dev verzi a ty inject metody právě využívám, ale stalo se mi že se mi to tam neinjectuje, tak nevím zda chyba anotace či chyba v nette ;) nemám tu poruce kód tak přesně nevím deklarace.

akadlec
Člen | 1326
+
0
-

@matej21
Takže vyzkoušel jsem tvé řešení, fungovalo ale bohužel jen částečně :( V tom system manageru mam inject metodu co mě tam vloží fasádu pro datový model, nicméně když je to otagováno jako run tak se to tam zřejmě vkládá dříve než se mě zaregistruje Gedmo rozšíření a pak to nezná v té entitě anotace.

David Matějka
Moderator | 6445
+
0
-

gedmo anotace inicializujes takhle ze?
na stejnym miste se prave pracuje s tema sluzbama otagovanyma jako „run“, takze bud to volani dat teda do presenteru, nebo do te metody initialize, ale v extensionu, ktere se nacte az po GedmoExtension

akadlec
Člen | 1326
+
0
-

Ano, přesně takto inicializuju GEDMO anotace.

  1. Tím voláním do presenteru máš namysli tak jak jsem to vyřešil na začátku?
  2. Do metody initialize máš namysli udělat si další konfigurační extension kde do metody afterCompile přidám vytvoření ten servisy? tedy něco jak to v tom tagu run ?
David Matějka
Moderator | 6445
+
0
-
  1. ano, nejak tak :)
  2. jj, vlastni compilerextension, ktery ve stylu toho tagu run tu sluzbu spusti s tim, ze to rozsireni bude registrovany az po gedmo rozsireni, takze se spusti uz s registrovanyma anotacema