Quick Start symfony DI (Függőség Injection) bemutatója

Által Steven Lloyd Watkin , szombat 14 augusztus 2010 14:21

Mi az a függőség injekció (DI)?

A függőség injekció olyan technika, amely lehetővé teszi a lazán csatolt objektumok egy szoftver alkalmazás. Általában, ha egy objektum hozzáférést igényel a funkciók más lenne instanced belsőleg vezető szorosan összekapcsolt rendszerekre. Megvalósításával függőség injekció is adja be a szükséges objektumokat használatra kész (néha említett inverzió ellenőrzés - NOB). Vegyük a következő példát:

  <? Php
 osztály DecisionMaker {
     public function makeDecision (array $ paraméterek) {
         / / Van szüksége az adatbázis adapter
         $ Dp = new DecisionParameters ();
         $ ParameterScore = $ dp-> getScore ($ paraméterek);
         / * ...  Néhány további logika ...  * /
         return ($ parameterScore> 50);
     }
 } 

Ez a kódrészlet azt mondják, hogy szorosan kapcsolódik a DecisionParameters objektumot. Átírta a fenti egy lazán összekapcsolt divat mi volna valami ilyesmit ....

  <? Php
 osztály DecisionMaker {
     Privát $ _dp;
     public function __construct ($ dp) {
         $ This-> _dp = $ dp;
     }
     public function makeDecision (array $ paraméterek) {
         $ ParameterScore = $ this-> _dp-> getScore ($ paraméterek);
         / * ...  Néhány további logika ...  * /
         return ($ parameterScore> 50);
     }
 } 

Miközben egyre előnyeit lazán kód vagyunk hozzá összetettsége olyan, hogy minden egyes alkalommal, amikor egy objektum futtatását is meg kell példányosítani a függőségeket, és adja át ezeket is. Például ez:

  $ Választás = új DecisionMaker ();
 echo $ választás-> makeDecision (array ("tevékenységi '=>" alacsony "," visszatérés "=>" nagy ")); 

Most válik:

  $ Dp = new DecisionParameters ();
 $ Választás = new DecisionMaker ($ dp);
 echo $ választás-> makeDecision (array ("tevékenységi '=>" alacsony "," visszatérés "=>" nagy ")); 

Ez a helyzet egyre inkább fájdalmas, mint a függőségek számát egy osztály emelkedett, és mi van, ha a függőségek maguk függőségek? Ez elég hamar egy tárgy közigazgatás rémálom! Adja függőség injekció tartályok (vagy keretek) ...

Függőség Injekciós tartályok / keret

Függőség injekció konténerek (vagy keretek) bonyolódik a folyamat az objektumok létrehozását, és az injekciós példányosítása a függőségeket, mielőtt visszatér egy példány a hívó fél.

Az Ön kódja helyett új objektumokat közvetlenül általunk kért egy példányt a tárgy a DI konténer. Az objektum vagyunk vissza már minden függőséget beadni, és a tárgy is készen áll.

Symfony Függőség injekció konténer

Symfony talán legismertebb ezek teljes stack MVC keretrendszer de ők is megjelent több, a közös komponensek használható önállóan. Például, a függőség injekció tartály fogunk beszélni itt, egy YAML elemző, a sablonrendszer motort, lásd symfony alkatrészek több.

A symfony DI konténer alapul, hogy a Spring Framework a Java .

Bootstrapping

Annak érdekében, hogy a bootstrap symfony függőség injekció keretében az általunk használt kód, a lent megtalálható. Úgy döntöttem, hogy használni YAML csak azért, mert a könnyen olvasható és beállít. A maximális sebesség érdemes írni ki a konténereket, hogy sima PHP (a symfony tartály nem teheti meg ezt még egyszer setup), vagy pedig az egész cache konténer segítségével Zend_Cache , vagy hasonló.

A telepítéshez symfony DI kövesse az utasításokat itt http://components.symfony-project.org/dependency-injection/installation , és add hozzá a saját útját.

  / / Betöltése symfony DI konténer
 igényelnek "sfServiceContainerBuilder.php";
 $ Konténer = új sfServiceContainerBuilder ();
 $ Loader = new sfServiceContainerLoaderFileYaml ($ konténer);
 $ Loader-> load (APPLICATION_PATH. "/ Config / di / services.yml '); 

Először is átadjuk egy új tárolóra, majd betöltjük a konfiguráció egy YAML fájlt. Megjegyzés: A DI konténer tudja tölteni config több formátumban, mint például az XML , YAML, PHP, és INI *. Én inkább magában foglalja egy közös YAML fájlt és import egyéb fájlokat belül van.

Több konfigurációs fájlokat lehet importálni, eltérő formátumban, az újabb definíciók felülírja azokat, amelyeket már meghatározott. Konfigurációs fájlok tartalmaznak utalásokat a tárgyak és paraméterek.

* INI csak akkor tudja meghatározni paraméterek, és nem tudja importálni más fájlokat

Beállítási példa

  behozatal:
 - {Forrás: daos.yml}

 paraméterek:
 felhasználónév: hamis

 szolgáltatások:
 # Ügyfél modell
 model.customer:
 osztály: Pro_Customer
 hívások:
 - [SetLogger, [@ utils.logger]]
 - [SetDao, [@ data.userdata.mysql]]
       - [SetUserName, [% username%]]

 # A termék modell
 model.product:
 osztály: Pro_Product
     érvek: [% username%, {type:% accesslevel%, lastlogin:% lastlogin%}]
 hívások:
 - [SetDao, [@ data.product.mysql]]

 # Logger
 utils.logger:
 osztály: Pro_Logger
     konstruktor: getInstance
 hívások:
 - [SetHandle, [@ utils.filewriter]] 

Azt hiszem, a fenti kódot meglehetősen magától értetődő, de az egyértelműség kedvéért leírom, minden egyes részét most.

Először is határozzuk meg néhány import (azaz más fájlokat feldolgozó), szeretek csoportban a konfigurációk például DAOs egy fájlban, közművek más és nevét a fájl megfelelően. Míg egy kicsit lassabban, hogy felgyorsítja a fenntartó a konfigurációs fájlokat. Az is lehet értelmezni fájlokat más formátumokban különböző behozatali zászlókat. A fájlok elemzett érdekében az újabb definíciók felülírását vagy módosító korábban meghatározott szolgáltatások / paramétereket.

Következő lépésként határozza meg a paramétert, ha egy paraméter általában bármilyen PHP változó típusa. Ezen a ponton nem tudtam, mi a felhasználónevét paramétert kell (Meg kell hitelesíteni, hogy!), Úgyhogy meg egy alapértelmezett értéket, és én majd felülírja ezt az értéket később. Megjegyzés, osztályok nem példányosított amíg nem kéri őket, így meghatározó paraméterek egy kicsit később is tökéletesen megfelel. Ezt követően én meg néhány szolgáltatás:

  1. Példányosítani Pro_Customer, át egy példányát az én logger a setLogger () metódus, add az én MySQL adatelérési objektumok (DAO), és add meg a felhasználónevet is. Minden alkalommal, amikor kértem az objektumhoz Szeretnék egy új példány
  2. Hozzon létre egy példányát Pro_Product, át érveket felhasználónév és egy options tömb a kivitelező. Miután példányosítását hívás setDao (), és adja át a terméket DAO
  3. Adj egy másolatot Pro_Logger, példányosítani ez használ a getInstance () metódus, és adja át egy példányt a fájl író objektumot keresztül setHandle () után a betöltött. Az én fájl író határozza meg egyik behozatal.

Belül a konfigurációs fájlok szolgáltatásokat hivatkozik Elejére beszúrás a név egy "@" szimbólumot, paramétereket hivatkozik Elejére beszúrás és hozzáfűző a "%" jelek, eg@utils.logger% username%.

Hozzáadása után az adatok betöltése

Néha nem tudom, mi a paraméterek értéke meg kell, amíg van bootstrapped, mint a mi felhasználóneveddel paraméter fölött. Annak érdekében, hogy felülírja az érték a offsetSet () módszerét alkalmazták először halad a paraméter nevét, majd az új értéket:

  $ Konténer-> offsetSet ('username', $ username); 

Első Tárgyak a tartály

Miután beállítás helyett példányosítása objektumokat közvetlenül most megy a DI tartályban kap példányok. A symfony DI nevezzük a getService () metódust, halad egy string, amely leírja a változó letölteni kívánt, például a

  $ Logger = $ konténer-> getService ("utils.logger '); 

Ez fogja a megfelelője:

  $ Logger = Pro_Logger:: getInstance ();
 $ FileWriter = új Pro_Writer_FileWriter ();
 $ Logger-> setHandler ($ fileWriter); 

Meg lehet határozni, ha a konténer van például egy szolgáltatás a hívó hasService () metódus, amely visszatér a logikai értéket.

Hogy nem szükséges, hogy hozzáférjen a tartály túl a legfelső szinten a kérelmet, mivel egyszer letöltést egy példányát az összes szükséges függőségek egészen a legmélyebb mélyén az alkalmazás már setup, és várja, hogy hívják.

Egység tesztelése

Függőség injekciót is az előnye, amely lehetővé teszi tárgyak vizsgálandó elszigetelten. Figyelembe a DecisionMaker osztályban például végrehajtása előtt a függőség injekció beállítása a vizsgálati eredmények is függ végrehajtásáról DecisionParameters osztály.

Amennyiben a DecisionParameters osztály visszatérő eltérő eredményeket tesztjeink indulhasson nem hibájukon kívül saját. Használata függőség injekció most már át a DecisionParameters tárgy, amely visszaadja az ismert / fix meghatározott eredmények bizonyos bemeneti paramétereket, most tesztelés DecisionMaker elkülönítve semmilyen külső tényező, azaz, ha a vizsgálatok kezdete ennek hiányában közvetlenül tulajdonítható valamit változó a DecisionMakeer osztályban. Ez különösen fontos, legyen ön támaszkodva vizsgálati adatokat egy adatbázisban a vizsgálathoz.

Alkalmazás konfiguráció

Az, ahogyan az az alkalmazás működését a termelési szerver elkerülhetetlenül különböznek a fejlesztői változat telepítése. Például, egy fejlesztői környezetben szintjét fakitermelés sokkal finomabb, mint a termelési rendszerben. Azáltal, hogy megváltoztatja a függőség injekció konténer konfigurációs fájlokat kissé (vagy elemzés egy további konfigurációs fájl) a megváltoztatása a viselkedés függ a környezet egyszerűvé válik.

Típus szerint hint a felületek helyett megvalósítások Amikor beállítja a függőségeket az is lehetséges, hogy a csere a összetevők kompatibilis alkatrészek néhány sor YAML vagy XML. Például előfordulhat, jelenleg a hozzáférést az adatbázishoz keresztül MySQL DAO (Data Access Object), de idővel előfordulhat, dolgozzon ki egy OEM, Zend_Db, vagy Tan végrehajtásában DAO. Felveszi az új átültetése a konfigurációs fájl hirtelen minden objektumot, hogy a használt a régi MySQL megvalósítás most már az új végrehajtási anélkül, hogy megtámadják a gyomrában az alkalmazás.

Notes

  • Azáltal, megosztott: igaz, a konfiguráció mi mindig ugyanilyen esetben egy objektum. Ez nagyon hasznos, ha foglalkozó tárgyakat tartalmazó források, mint az adatbázis-kapcsolatok, fájlkezelők, stb.
  • Két módszer van, amelyekkel függőségek lehet beadni. Az egyik az, hogy adja át a függőségeket a kivitelező, vagy pedig keresztül szabályozóval módszerek. Az általánosan elfogadott minta átadni szükséges függőségeket keresztül tervezett és Opcionális keresztül alkotóinak. Az én személyes preferencia használni alkotóinak mindent, de ez meg az egyéni fejlesztő

Végül ....

Valamint egy rövid beszélgetés a függőség injekció és annak előnyeit és hátrányait ez is egy gyors-start végrehajtási útmutatójának symfony függőség injekció Container ... remélem láttad, hogy ez meglepően gyorsan és egyszerűen. Innen lesz képes elkezdeni használata függőséget injekció révén a kérelmet, és nézd, hogy segítségével sokkal több a fejlett funkciók (bár az egyszerű példa lefedi a legtöbb funkció lesz szükség). Mint mindig azt pont, hogy a kézikönyv további információt.

4 Válasz-hoz "Quick Start symfony DI (Függőség Injection) bemutatója"

  1. [...] Ez az üzenet már említettük a Twitter Vincent Jousse, Steven Lloyd Watkin. Steven Lloyd Watkin mondta: http://bit.ly/cUO2ov Gyors kezdete # symfony függőség injekció keret # php # zf [...]

  2. Hari KT azt mondja:

    Nagy cikk.
    Nekem van egy kétséges most. Amikor bootstrapping vagyunk betölteni az YAML konfigurációs fájlokat. Tehát ez azt új objektumok létrehozásához minden, amit nem kell?
    Pl: Van egy osztály Valami, ami csak néha. Tehát nem is létrehoz egy objektumot, vagy ez elég okos ahhoz, hogy tölthető AUTOLOAD akkor működik, ha hívlak getInstance () metódus. Nem kaptam, hogy, azaz miért.

    Köszönöm

  3. Steven Lloyd Watkin azt mondja:

    Nem, osztályok terhelve, amikor először szükség.

    A getInstance () példa az osztály példányai, mint:
    $ Class = Osztály:: getInstance ();
    Ahelyett, hogy:
    $ Class = new Class ();
    Általában ez a végrehajtása során az egyedüli mintát.

  4. [...] Mellyel használhatja DI a projekt egy könnyű út. Steven Lloyd Watkin tölteni az idejét beírni a gyorsindítás tutorial.It Érdemes megemlíteni, hogy symfony DI Container egy önálló könyvtár elérhető a symfony [...]

Hagy egy Válaszol













Panoráma téma Themocracy

15 online látogató jelenleg
5 vendég, 10 botoktól, 0 tag
Max. látogatók ma: 17., 00:28 UTC
Ebben a hónapban: 26., 2011/07/05 12:35 UTC
Ebben az évben: 130 at 28-03-2011 22:40 UTC
Az összes idő: 130 at 28-03-2011 10:40 UTC