Хуткі старт Symfony DI (Dependency Injection) Падручнік

Па Стывен Лойд Уоткин , у суботу 14 жніўня 2010 02:21 вечара

Што такое Dependency Injection (DI)?

Залежнасць ін'екцыі тэхніка, якая дазваляе слаба звязаных аб'ектаў у праграмным дадатку. Наогул, калі аб'ект патрабуе доступу да функцыянальнасці іншага было б асобнік ўнутрана вядучых жорстка звязаных сістэмах. Да рэалізацыі Dependency Injection мы ўводзім патрэбныя аб'екты гатовыя да выкарыстання (часам таксама завецца інверсіяй кантролю - МАК). Разгледзім наступны прыклад:

  <? PHP
 твар, якое прымае рашэння класа {
     грамадскага makeDecision функцыі (масіў $ параметраў) {
         / / Вам патрэбныя адаптара БД
         $ DP = новы DecisionParameters ();
         $ ParameterScore = $ DP-> getScore ($ параметраў);
         / * ...  Яшчэ некалькі прыняцця рашэння ...  * /
         вяртання ($ parameterScore> 50);
     }
 } 

Гэты фрагмент кода называецца цесна звязаны з DecisionParameters аб'екта. Перапісваючы вышэй у слабосвязанных моды мы б нешта накшталт ....

  <? PHP
 твар, якое прымае рашэння класа {
     прыватных $ _dp;
     публічную функцыю __construct ($ DP) {
         $ Гэтым-> _dp = $ DP;
     }
     грамадскага makeDecision функцыі (масіў $ параметраў) {
         $ = $ ParameterScore гэтым-> _dp-> getScore ($ параметраў);
         / * ...  Яшчэ некалькі прыняцця рашэння ...  * /
         вяртання ($ parameterScore> 50);
     }
 } 

Хоць атрыманне выгады слабосвязанных кода мы дадаем складанасці такі, што кожны раз асобніка аб'екта, мы таксама павінны асобнік яго залежнасцяў і перадаць іх у занадта. Напрыклад, гэта:

  $ = Выбар новых твар, якое прымае рашэнні ();
 Рэха $ выбар-> makeDecision (Array ('намаганні' => 'нізкі', 'вяртанне' => 'высокі')); 

Зараз становіцца:

  $ DP = новы DecisionParameters ();
 $ = Выбар новых твар, якое прымае рашэнні ($ DP);
 Рэха $ выбар-> makeDecision (Array ('намаганні' => 'нізкі', 'вяртанне' => 'высокі')); 

Гэтая сітуацыя становіцца ўсё больш хваравітым, як лік залежнасцяў для класа павялічваецца, а што, калі залежнасці самі залежнасцяў? Гэта можа вельмі хутка стаць кашмарам аб'екта адміністрацыі! Калі ласка, увядзіце кантэйнераў ін'екцыі залежнасцяў (або структуры) ...

Dependency Injection Кантэйнеры / Frameworks

Унясенне залежнасцяў кантэйнераў (або рамкі) кіраваць працэсам стварэння аб'екта; асобнікаў і ін'екцыйных якія-небудзь залежнасці, перш чым вярнуцца асобнік абанента.

У сваім кодзе, а не ствараць новыя аб'екты непасрэдна мы просім копію аб'екта з кантэйнера DI. Аб'ект, які мы вярнуліся ўжо ўсё яго залежнасці ўводзілі і аб'ект гатовы да працы.

Symfony dependency Injection кантэйнераў

Symfony, верагодна, самы вядомы за іх поўны стэк MVC рамках аднак яны таксама выпусцілі шэраг кампанентаў, якія могуць быць выкарыстаны самастойна. Напрыклад, ін'екцыі кантэйнер залежнасць мы збіраемся казаць аб тут, YAML парсер шаблонаў рухавіка, гл Symfony кампанентаў для больш.

DI кантэйнера Symfony заснаваны на што з Spring Framework ў Java .

Пачатковая загрузка

Для загрузкі ін'екцыі Symfony залежнасці рамкі мы выкарыстоўваем код ніжэй. Я вырашыў выкарыстоўваць YAML толькі таму, што яе лёгка чытаць і ўстаноўкі. Для максімальнай хуткасцю вы можаце запісаць вашыя кантэйнеры ў звычайны PHP (кантэйнер Symfony можа зрабіць гэта для вас Пасля ўстаноўкі), ці ж кэш ўвесь кантэйнер выкарыстаннем Zend_Cache , ці аналагічны.

Каб усталяваць Symfony DI выконвайце інструкцыі, якія змяшчаюцца тут http://components.symfony-project.org/dependency-injection/installation , і дадаць яго ў шляху.

  / / Загрузка кантэйнера Symfony DI
 патрабуюць "sfServiceContainerBuilder.php;
 $ Кантэйнер = новы sfServiceContainerBuilder ();
 $ = Пагрузчык новы sfServiceContainerLoaderFileYaml ($ кантэйнера);
 $ Пагрузчык-> Load (APPLICATION_PATH "/ Config / ды / 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]] 

Я думаю, што прыведзены вышэй код з'яўляецца дастаткова зразумелыя, але для яснасці я растлумачу, кожная частка цяпер.

Перш за ўсё мы вызначым некаторыя імпарту (г.зн. іншыя файлы для разбору), мне падабаецца гурт маёй канфігурацыі, напрыклад аб'екты DAO ў адным файле, камунальныя паслугі ў іншай і імя файла адпаведна. Хоць трохі павольней, гэта паскарае абслугоўванне канфігурацыйных файлаў. Яе таксама можна прааналізаваць файлы іншых фарматаў, выкарыстоўваючы розныя сцягі імпарту. Файлы апрацоўваюцца ў парадку з новымі азначэннямі перазапісу або змены раней вызначаных паслуг / параметраў.

Далей мы вызначым параметр, параметр можа наогул быць любога тыпу PHP зменнай. На дадзены момант я не ведаў, што маё імя карыстальніка параметр павінен быць (мне трэба для аўтэнтыфікацыі для гэтага!), Так я вызначыў значэнне па змаўчанні, і я буду перапісваць, што значэнне пазней. Звярніце ўвагу, класы не асобнік, пакуль вы просіце іх так, якія вызначаюць параметраў крыху пазней гэта выдатна. Пасля гэтага я вызначаю некаторыя паслугі:

  1. Асобніка Pro_Customer, перадаць асобнік маёй рэгістратар для setLogger () метад, дадаць у мой MySQL аб'ект доступу да дадзеных (DAO), і перадаць імя карыстальніка, а таксама. Кожны раз, калі я прашу для гэтага аб'екта я хачу новы асобнік
  2. Стварыць экзэмпляр Pro_Product, перадаваць аргументы імя карыстальніка і варыянты масіў у канструктар. Пасля выкліку асобніка setDao () і перадаць яго мой прадукт DAO
  3. Дайце мне копію Pro_Logger, экзэмпляр, выкарыстоўваючы GetInstance () і перадаць копію майго аб'екта пісьменнік файл праз SetHandle () адзін раз яго загружаны. Мой файл пісьменніка вызначаецца ў адным з маіх імпарту.

У файлах канфігурацыі паслуг на якія спасылаецца папярэднічаючы імя з @ "сімвал", параметры спасылкі, дадаючы і дадання з '%' сімвалаў, eg@utils.logger% Імя карыстальніка%.

Даданне дадзеных пасля загрузкі

Часам вы не ведаеце, што значэнні параметраў павінны быць, пакуль Вы не загружалі, як з нашымі імя карыстальніка параметр вышэй. Для таго, каб перазапісаць значэнне offsetSet () метад выкарыстоўваецца, па-першае праходзяць імя параметра з наступным яго новае значэнне:

  $ Кантэйнер-> offsetSet ("Імя карыстальніка", $ імя карыстальніка); 

Як аб'ект з кантэйнера

Пасля ўстаноўкі, а не асобнікаў аб'ектаў непасрэдна цяпер перайсці да кантэйнера DI, каб атрымаць асобнікі. З Symfony DI мы называем GetService () метад, якая праходзіць у радок, якая апісвае зменныя, якія трэба загрузіць, напрыклад,

  $ = $ Рэгістратар кантэйнер-> GetService ('utils.logger'); 

Гэта будзе выконваць эквівалент:

  $ Logger = Pro_Logger:: GetInstance ();
 $ FileWriter = новы Pro_Writer_FileWriter ();
 $ Рэгістратар-> SetHandler ($ FileWriter); 

Гэта можна вызначыць, калі кантэйнер мае асобнік службы па тэлефоне hasService () метад, які вяртае лагічнае значэнне.

Яго не абавязкова мець доступ да кантэйнера за межы верхняга ўзроўню вашага дадатку, паколькі пасля атрымання асобніка ўсіх неабходных залежнасцяў аж да глыбінь вашага дадатку ўжо ўстаноўка і чакаюць, каб называць.

Модульнае тэставанне

Унясенне залежнасцяў таксама мае дадатковае перавага дазваляе аб'ектаў для іх выпрабаванні ў ізаляцыі. Узяўшы прыклад класа схема прыняцця рашэння да рэалізацыі ін'екцый ўстаноўкі залежнасць вынікаў выпрабаванняў былі таксама залежыць ад рэалізацыі класа DecisionParameters.

Калі клас DecisionParameters вяртаць розныя вынікі нашых тэстаў можа пачаць правальваючыся не па нашай віне. Выкарыстаньне залежнасцяў ін'екцый цяпер мы можам перайсці ў DecisionParameters аб'ект, які вяртае вядомых і / або фіксаваны набор вынікаў для пэўных ўваходных параметрах, мы цяпер тэставанне твар, якое прымае рашэнні ў ізаляцыі ад любых знешніх фактараў, г.зн., калі нашы тэсты пачаць адваротным выпадку гэта можа быць непасрэдна аднесены да чаго-то Змена ў класе DecisionMakeer. Гэта асабліва важна, вы павінны спадзявацца на тэставых даных з базы дадзеных для тэсціравання.

Настройка прыкладанняў

Тое, якім чынам ваша дадатак вядзе сябе на працоўным сэрвэры непазбежна будзе адрознівацца ад вашага развіцця ўстаноўкі. Напрыклад, у асяроддзі распрацоўкі ўзровень рэгістрацыі будзе значна больш дэталёва, чым на вытворчай сістэмы. Змяняючы вашу залежнасць ін'екцыі файлаў-кантэйнераў канфігурацыі трохі (або разбору дадатковы файл канфігурацыі) змяненне паводзінаў у залежнасці ад асяроддзя стала прасцей.

Па тыпе намякаючы на ​​межах, а не рэалізацыі пры ўстаноўцы залежнасцяў яго таксама можна абмяняць кампаненты для сумяшчальных кампанентаў з некалькімі радкамі YAML ці XML. Напрыклад, вы можаце ў цяперашні час доступ да базы дадзеных MySQL з дапамогай DAO (Data Access Object), але з часам вы можаце развіваць PDO, Zend_Db, або дактрына ажыццяўлення гэтай DAO. Пры даданні новай рэалізацыі ў вашым файле канфігурацыі раптам ўсе аб'екты, якія выкарыстоўвалі старыя ажыццяўлення MySQL ў цяперашні час выкарыстоўваюць новыя ажыццяўлення без неабходнасці атакаваць нетрах вашага дадатку.

Нататкі

  • Усталёўваючы агульныя: сапраўды ў канфігурацыі мы заўсёды давалі той жа экземпляр аб'екта. Гэта вельмі карысна пры рабоце з аб'ектамі, якія ўтрымліваюць рэсурсы, такія як злучэння з базай дадзеных, дэскрыптары файлаў і г.д.
  • Ёсць два метаду залежнасцяў могуць быць уведзеныя. Адзін з іх праходзяць залежнасцяў з дапамогай канструктара, ці ж праз сетэр метадамі. Агульнапрынятай карціны прайсці неабходныя залежнасці з дапамогай канструктара і опцыямі праз сетэр. Маё асабістае перавагу з'яўляецца выкарыстанне ўстаноўкі для ўсяго, але гэта да асобных распрацоўшчыкаў

І нарэшце ....

Нараўне з кароткага абмеркавання ін'екцыі залежнасцяў і яго перавагі і недахопы гэтага таксама Кароткае кіраўніцтва па ажыццяўленні Symfony Dependency Injection кантэйнер ... спадзяюся, вы бачылі, што гэта дзіўна хутка і лёгка. Адсюль вы зможаце пачаць выкарыстоўваць Dependency Injection праз вашае прыкладанне і паглядзець на выкарыстанне многіх іншых дадатковых функцый (хоць просты прыклад ахоплівае пераважная большасць функцыянальных магчымасцяў вы будзеце патрабаваць). Як заўсёды, я паказваю вам кіраўніцтва для атрымання дадатковай інфармацыі.

4 Адказы на "Хуткі старт Symfony DI (Dependency Injection) Падручнік"

  1. [...] Гэта паведамленне было згадана на шчабятаць па-Вінсэнт Jousse, Стывен Лойд Уоткин. Стывен Лойд Уоткин сказаў: http://bit.ly/cUO2ov Хуткі старт для # Symfony рамках ін'екцыі залежнасцяў # PHP # ZF [...]

  2. Хары KT кажа:

    Вялікая артыкул.
    У мяне ёсць сумненні ў цяперашні час. Пры пачатковай загрузцы мы загрузцы YAML файлы канфігурацыі. Ці так гэта, стварыць аб'екты для ўсіх, якія нам не патрэбныя?
    Для, напрыклад: у мяне ёсць што-то класа, якая выкарыстоўваецца толькі часам. Гэтак жа ён стварае аб'ект ці гэта дастаткова разумныя, каб загрузіць праз аўтазагрузку функцый, калі я тэлефаную GetInstance () метад. Я не атрымаў, што, т. е. чаму.

    Дзякуй

  3. Не, класы загружаюцца толькі, калі яны ўпершыню патрабуецца.

    У GetInstance () Прыклад асобніка класа, як:
    $ Класа класа =:: GetInstance ();
    Замест таго, каб:
    $ = Класа новага класа ();
    Звычайна гэта выкарыстоўваецца пры рэалізацыі Singleton карціны.

  4. [...] Дазваляючы выкарыстоўваць DI ў вашым праекце не лёгкі шлях. Стывен Лойд Уоткин марнаваць свой час на напісанне хуткага tutorial.It пачаць "варта адзначыць, што Symfony DI Кантэйнер асобную бібліятэку даступныя як Symfony [...]

Напісаць адказ













Панарама Тэма Themocracy

5 наведвальнікаў онлайн
4 гасцей, 1-ботаў, 0 карыстальнікаў
Макс наведвальнікаў сёння: 14 г., 07:34 UTC
У гэтым месяцы: 26 у 2011/05/07 12:35 раніцы UTC
У гэтым годзе: 130 у 2011/03/28 10:40 вечара UTC
За ўвесь час: 130 у 2011/03/28 10:40 вечара UTC