Generált factory-k
A Nette DI képes automatikusan generálni factory kódot interfészek alapján, ami megkíméli Önt a kódírástól.
A factory egy olyan osztály, amely objektumokat gyárt és konfigurál. Tehát átadja nekik a függőségeiket is. Kérjük, ne keverje össze a factory method tervezési mintával, amely a factory-k specifikus felhasználási módját írja le, és nem kapcsolódik ehhez a témához.
Hogy néz ki egy ilyen factory, azt a bevezető fejezetben mutattuk be:
A Nette DI képes automatikusan generálni a factory kódot. Mindössze annyit kell tennie, hogy létrehoz egy interfészt,
és a Nette DI legenerálja az implementációt. Az interfésznek pontosan egy create
nevű metódussal kell
rendelkeznie, és deklarálnia kell a visszatérési típust:
Tehát az ArticleFactory
factorynak van egy create
metódusa, amely Article
objektumokat
hoz létre. Az Article
osztály például így nézhet ki:
A factoryt hozzáadjuk a konfigurációs fájlhoz:
A Nette DI legenerálja a factory megfelelő implementációját.
A kódban, amely a factoryt használja, így kérünk egy objektumot az interfész alapján, és a Nette DI a generált implementációt használja:
Paraméterezett factory
A create
factory metódus elfogadhat paramétereket, amelyeket aztán átad a konstruktornak. Egészítsük ki
például az Article
osztályt a cikk szerzőjének ID-jával:
A paramétert hozzáadjuk a factoryhoz is:
Annak köszönhetően, hogy a konstruktorban és a factoryban lévő paraméter neve ugyanaz, a Nette DI teljesen automatikusan átadja őket.
Haladó definíció
A definíciót többsoros formában is le lehet írni az implement
kulcs használatával:
Ezzel a hosszabb írásmóddal további argumentumokat lehet megadni a konstruktorhoz az arguments
kulcsban, és
kiegészítő konfigurációt a setup
segítségével, ugyanúgy, mint a normál
szolgáltatásoknál.
Példa: ha a create()
metódus nem fogadná el a $authorId
paramétert, megadhatnánk egy fix
értéket a konfigurációban, amelyet átadnánk az Article
konstruktorának:
Vagy fordítva, ha a create()
elfogadná a $authorId
paramétert, de az nem lenne része a
konstruktornak, és a Article::setAuthorId()
metódussal adnánk át, akkor a setup
szekcióban
hivatkoznánk rá:
Accessor
A Nette a factory-k mellett ún. accessorokat is tud generálni. Ezek olyan objektumok, amelyeknek van egy get()
metódusa, amely egy bizonyos szolgáltatást ad vissza a DI konténerből. A get()
ismételt hívása mindig
ugyanazt a példányt adja vissza.
Az accessorok lazy-loadingot biztosítanak a függőségeknek. Tegyük fel, hogy van egy osztályunk, amely hibákat ír egy
speciális adatbázisba. Ha ez az osztály konstruktorfüggőségként kapná meg az adatbázis-kapcsolatot, a kapcsolatot mindig
létre kellene hozni, bár a gyakorlatban hiba csak kivételesen fordul elő, és így a kapcsolat legtöbbször kihasználatlan
maradna. Ehelyett az osztály átad egy accessort, és csak akkor jön létre az adatbázis objektum, amikor annak
get()
metódusát meghívják:
Hogyan hozzunk létre accessort? Csak írjunk egy interfészt, és a Nette DI legenerálja az implementációt. Az
interfésznek pontosan egy get
nevű metódussal kell rendelkeznie, és deklarálnia kell a visszatérési
típust:
Az accessort hozzáadjuk a konfigurációs fájlhoz, ahol a szolgáltatás definíciója is található, amelyet vissza fog adni:
Mivel az accessor PDO
típusú szolgáltatást ad vissza, és a konfigurációban csak egy ilyen szolgáltatás
van, pontosan azt fogja visszaadni. Ha több ilyen típusú szolgáltatás lenne, a visszaadott szolgáltatást név szerint
határoznánk meg, pl. - PDOAccessor(@db1)
.
Többszörös factory/accessor
Eddig a factory-ink és accessoraink mindig csak egy objektumot tudtak gyártani vagy visszaadni. De nagyon könnyen
létrehozhatunk többszörös factory-kat is accessorokkal kombinálva. Egy ilyen osztály interfésze tetszőleges számú
create<name>()
és get<name>()
nevű metódust tartalmazhat, pl.:
Tehát ahelyett, hogy több generált factoryt és accessort adnánk át, egy komplexebb factoryt adunk át, amely többet tud.
Alternatívaként több metódus helyett használhatjuk a get()
-et paraméterrel:
Ekkor igaz, hogy a MultiFactory::getArticle()
ugyanazt csinálja, mint a
MultiFactoryAlt::get('article')
. Az alternatív írásmódnak azonban az a hátránya, hogy nem egyértelmű, milyen
$name
értékek támogatottak, és logikailag nem lehet megkülönböztetni a különböző visszatérési
értékeket a különböző $name
-ekhez az interfészben.
Definíció listával
Ezzel a módszerrel definiálhatunk többszörös factoryt a konfigurációban:
Vagy a factory definíciójában hivatkozhatunk létező szolgáltatásokra referenciával:
Definíció tagekkel
A második lehetőség a tageket használni a definícióhoz: