Брзо вклучување Symfony ДИ (Зависност вбризгување) Почетен курс

Со Стивен Лојд Watkin , сабота 14 август 2010 14:21

Што е Зависност вбризгување (Di)?

Зависност инјекција е техника која им овозможува за лабаво заедно објекти во рамките на софтверска апликација. Општо земено, ако некој предмет бара пристап до функционалноста на друга дека ќе се инстанцира внатрешно доведува до цврсто заедно системи. Со имплементирањето на зависност инекција се внесе потребните предмети подготвен за употреба (понекогаш и од инверзија на контрола - МОК). Земете го следниот пример:

  <? Php
 класа DecisionMaker {
     јавна функција makeDecision (низа $ параметри) {
         / / Потребата за базата на податоци адаптер
         $ Dp = new DecisionParameters ();
         $ ParameterScore = $ ДП-> getScore ($ параметри);
         / * ...  Некои повеќе одлука логика ...  * /
         се врати ($ parameterScore> 50);
     }
 } 

Ова парче код се вели дека е цврсто поврзан со DecisionParameters објект. Пренапишување на горенаведената во лабаво заедно мода ние ќе мора нешто како ....

 <? Php класа DecisionMaker {приватна $ _dp; јавна функција __construct ($ ДП) {$ ова-> _dp = $ ДП;} јавна функција makeDecision (низа $ параметри) {$ parameterScore = $ ова-> _dp-> getScore ($ параметри); / * ...  Некои повеќе одлука логика ...  * / Враќање ($ parameterScore> 50);}} 

Додека се здобие со придобивките на лабаво заедно код сме додавајќи сложеност, како што секој пат кога објектот е инстанцира, ние исто така мора да се показ своите зависности и да помине во овие премногу. На пример, ова:

  $ Избор = new DecisionMaker ();
 echo $ избор-> makeDecision (array ('напор' => 'низок', 'врати' => 'високо')); 

сега станува:

  $ Dp = new DecisionParameters ();
 $ Избор = new DecisionMaker ($ ДП);
 echo $ избор-> makeDecision (array ('напор' => 'низок', 'врати' => 'високо')); 

Оваа ситуација станува болно како и бројот на зависности за класа е зголемен, и што ако зависности и самите имаат зависности? Ова многу брзо може да стане објект администрација кошмар! Внесете зависност инекција контејнери (или рамка) ...

Зависност инекции / рамки

Зависност инекција контејнери (или рамка) се справи со процесот на креирањето; инстанцирање и инјектирање било зависности пред да се врати на пример до повикувачот.

Во твојот код, а не се создадат нови објекти директно ги побарате копија на објектот од садот DI. Целта ни е да сме се врати веќе има сите зависности инјектира и објектот е подготвен да си замине.

Symfony Зависност вбризгување на контејнерот

Symfony е веројатно најдобро позната за нивна целосна магацинот MVC рамка, сепак тие, исто така, објави бројот на компоненти кои може да се користи самостојно. На пример, на зависност инекција контејнер ние нема да зборуваме за тука, YAML парсер, а templating мотор, видете Symfony компоненти за повеќе.

На Symfony DI сад е врз основа на таа од Рамковниот пролет во Јава .

Bootstrapping

Со цел да се подигање на зависност Symfony инекција рамка се користи кодот за учество подолу. Јас избрав да го користите YAML само затоа што е лесно да се чита и подесување. За максималната брзина, можеби ќе сакате да пишувате од вашиот контејнери за обичен PHP (садот Symfony може да го направи тоа за вас еднаш подесување), или алтернативно, кешот на целиот контејнер користење Zend_Cache , или слично.

За да го инсталирате Symfony DI следете ги инструкциите се вклучени тука http://components.symfony-project.org/dependency-injection/installation , и додадете го во вашата патека.

  / / Вчитај ја Symfony DI контејнер
 бараат "sfServiceContainerBuilder.php ';
 $ Контејнер = new sfServiceContainerBuilder ();
 $ Натоварувач = new sfServiceContainerLoaderFileYaml ($ контејнер);
 $ Натоварувач-> load (APPLICATION_PATH '/ config / di / services.yml.); 

Прво ние показ за нови сад, а потоа ние оптоварување нашите конфигурација од датотека YAML. Напомена: сад DI може да се вчита конфигурацијата од неколку формати како што се XML , YAML, PHP и INI *. Имам навика да се вклучуваат еден YAML датотека и увоз од други датотеки во таму.

Неколку конфигурациони датотеки може да се внесуваат со користење на различни формати, новите дефиниции пребрише оние кои се веќе дефинирани. Конфигурациски датотеки може да вклучува повикувања на објекти и параметри.

* INI е само можност да се дефинираат параметрите и е неспособен за увоз на други датотеки

Пример конфигурација

  увозот:
 - {Ресурси: daos.yml}

 параметри:
 Корисничко име: лажни

 услуги:
 # Клиенти модел
 model.customer:
 класа: Pro_Customer
 повици:
 - [SetLogger, [@ utils.logger]]
 - [SetDao, [@ data.userdata.mysql]]
       - [SetUserName, [% корисничко име%]]

 # Производ модел
 model.product:
 класа: Pro_Product
     аргументи: [% корисничко име%, {тип:% accesslevel%, lastlogin:% lastlogin%}]
 повици:
 - [SetDao, [@ data.product.mysql]]

 # Logger
 utils.logger:
 класа: Pro_Logger
     градител: getInstance
 повици:
 - [SetHandle, [@ utils.filewriter]] 

Мислам дека е прилично кодот погоре, но само објаснување на јасност ќе објаснам секој дел сега.

Најпрво се дефинира некои увоз (т.е. други фајлови да го анализирам), сакам да ми група конфигурации на пример DAOs во еден фајл, комунални услуги во друга и името на фајлот. Иако малку побавно го забрзува одржување на конфигурациски датотеки. Нејзините исто така е можно да ја разложам датотеки на други формати со различни увоз знамиња. Додадени фајлови се расчленуваат, со цел да се пребрише со нови дефиниции или измени претходно дефинирани услуги / параметри.

Следна ја дефинираме како параметар, параметар генерално може да биде било променлива PHP тип. Во овој момент јас не знам што ми корисничко име параметар треба да биде (ми треба да се најавам за тоа!), Па јас сум се дефинира стандардна вредност и ќе ги избрише таа вредност подоцна. Имајте на ум, класи не се инстанцира, додека не се прашуваат за нив, па дефинирање параметри малку подоцна е совршено добро. По тоа јас се дефинираат некои услуги:

  1. Показ Pro_Customer, поминуваат на пример на мојот дрвосечач на setLogger () метод, да додадете во мојот MySQL, пристап до податоци објект (DAO), и да помине во корисничко име, исто така. Секој пат кога ќе го прашувам за овој објект Сакам нова инстанца
  2. Креирај инстанца на Pro_Product, поминуваат аргументите на корисничко име и опции низа на конструкторот. По инстанцирање повик setDao () и да го мојот производ DAO
  3. Дај ми копија од Pro_Logger, показ тоа со користење на getInstance () метод и да помине копија на мојот фајл писател објект преку setHandle () еднаш својата вчитан. Мојот датотека писател е дефиниран во еден од моите увоз.

Во рамките на конфигурациските датотеки услуги се референцирани со статусната линија за името, со '@' симбол, параметри се референцирани со статусната линија и дополнувања со '%' симболи, eg@utils.logger% корисничко име%.

Додавање на податоци пост вчитување

Понекогаш не знаеш што вредноста на параметри треба да се до после имаш bootstrapped, како и со нашите корисничко име параметарот горе. Со цел да се замени вредноста на offsetSet () метод се применува, прво полагање на параметар име проследено со својата нова вредност:

  $ Контејнер-> offsetSet ('име', $ корисничко име); 

Прв објекти од контејнерски

Откако подесување наместо инстанцирање предмети директно ние сега да одат во контејнер DI да се случаи. Со Symfony DI ние го нарекуваме getService () метод, минува во серијата, која ја опишува на променливата која сакате да се потсетите, на пример,

  $ Дрвосечач = $ контејнер-> getService ('utils.logger'); 

Ова ќе направи еквивалент на:

  $ Дрвосечач = Pro_Logger:: getInstance ();
 $ FileWriter = new Pro_Writer_FileWriter ();
 $ Logger-> setHandler ($ fileWriter); 

Можно е да се утврди дали контејнерот има пример на услугата со повикување на hasService () метод, кој враќа логичка вредност.

Нејзините не е потребно да имаат пристап до контејнерот надвор од највисоко ниво на вашата апликација, бидејќи еднаш во прибирањето на пример сите барани зависности утврдување на право на најдлабоките длабочините на вашата апликација се веќе поставување и чекаат да бидат повикани.

Единица за тестирање

Зависност инјектирање, исто така, е од дополнителна корист им се дозволи на објекти за да бидат тестирани во изолација. Преземање на класа DecisionMaker пример пред спроведување на зависност инекција подесување нашиот тест резултатите беа, исто така, зависи од имплементацијата на класата DecisionParameters.

Доколку DecisionParameters класа врати различни резултати на нашите тестови не би можеле да почнат во текот без вина на нашите сопствени. Користејќи зависност инекција можеме сега помине во DecisionParameters објект кој се враќа познат / фиксни сет на резултатите за некои влезни параметри, ние сме сега тестирање DecisionMaker во изолација од сите надворешни фактори, односно ако нашата тестови на проектот не се стори тоа може да биде директно се припишува на нешто промена во класата DecisionMakeer. Ова е особено важно што треба да се потпира на податоците од тестирањата од базата на податоци за тестирање.

Примена Конфигурација

Начинот на кој вашето барање се однесува на Вашето производство сервер неизбежно ќе се разликува од развојот подесување. На пример, во развој на животната средина на ниво на најавите ќе биде многу повеќе од зрнести на вашиот систем на производство. Со менување на вашата зависност инекција контејнер конфигурациски датотеки малку (или парсирање дополнителен конфигурациската датотека) за менување на однесување во зависност од животната средина се прави едноставна.

Според видот алудирајќи на интерфејси наместо имплементации кога поставување на вашиот зависности својата, исто така, е можно да се разменуваат надвор компоненти за компатибилни компоненти со неколку линии на YAML или XML. На пример, можете да пристапите во моментов вашата база на податоци преку MySQL DAO (пристап до податоци Предметот), но со време можеби ќе се развие ЗНП, Zend_Db, или доктрина спроведувањето на оваа Дао. Со додавање на нова институција во вашиот конфигурационен фајл одеднаш сите предмети што се користат на старите MySQL имплементација сега се користат својата нова институција, без потреба да го нападне утробата на вашата апликација.

Белешки

  • Со поставување на заеднички: точно во конфигурациската ние сме секогаш со оглед на истата инстанца на објектот. Ова е многу корисно кога се занимаваат со предмети кои содржат ресурси како база на податоци конекции, датотеката рачки, etc
  • Постојат два методи со кои може да се инјектираат зависности. Една од нив е да се помине со зависностите на конструкторот, или пак преку словослагател методи. Општоприфатените шема е потребно да помине зависности преку конструкторот и optionals преку положувачи. Мој личен избор е да се користи за положувачи на сè, но тоа е до поединецот инвеститорот

Конечно ....

Заедно со кратка дискусија за зависноста инјектирање и за неговите предности и недостатоци ова исто така е брз старт водич за спроведување на Symfony Зависност вбризгување на контејнерот ... се надевам дека сте виделе дека тоа е зачудувачки брзо и лесно. Од тука ќе бидат во можност да почнат да користат зависност вбризгување преку вашата апликација и да бараат да се користат многу повеќе од напредни опции (иако едноставен пример покрива огромното мнозинство на функционалност ќе бараат). Како и секогаш ти се укаже на прирачник за повеќе информации.

4 Responses to "Quick Start Symfony ДИ (Зависност вбризгување) Почетен курс"

  1. [...] Овој пост беше споменато на Twitter од страна на Винсент Jousse, Стивен Лојд Watkin. Стивен Лојд Watkin рече: http://bit.ly/cUO2ov Брз почеток за # symfony зависност инекција рамка # # php ZF [...]

  2. Одлична статија.
    Имам сомнеж сега. Кога bootstrapping сме вчитувањето на yaml конфигурациски датотеки. Па дали тоа се создаде објекти за сите, што не ни треба?
    За пример: Имам една класа Нешто кое се користи само понекогаш. Значи, не се создава некој предмет или тоа е доволно паметен за да се вчита преку autoload функции кога сум повикувајќи getInstance () метод. Јас не се тоа, односно зошто.

    Ви благодариме

  3. Не, класи се вчитуваат само кога тие се првите задолжителни.

    Во getInstance () пример класата е инстанцира како што се:
    $ Class = Класа:: getInstance ();
    Наместо:
    $ Class = новите Класа ();
    Општо земено, ова е се користи при спроведување на Синглтон шема.

  4. [...] Ви овозможи да го користите DI во вашиот проект на лесен начин. Стивен Лојд Watkin поминуваат своето време на пишување на брз почеток tutorial.It е вреди да се спомене дека Symfony DI садот е самостоен библиотека на располагање како Symfony [...]

Оставете Одговори













Панорама Тема од Themocracy

8 посетители онлајн сега
6 Гости, 2-ботови, 0 членови
Макс посетители денес: 17 во 00:28 UTC
Овој месец: 26 во 2011/07/05 12:35 UTC
Оваа година: 28-03-2011 во 130 22:40 UTC
Сите времиња: 130 на 28-03-2011 10:40 UTC