Quick Start Symfony DI (dependency iniksyon) Tutorial
Ano ang dependency iniksyon (DI)?
Dependency iniksyon ay isang pamamaraan na nagbibigay-daan para maluwag kaisa bagay sa loob ng isang application software. Kadalasan kung ang isang bagay ay kailangan ng access sa mga functionality ng ibang magiging instantiated loob na humahantong sa mahigpit kaisa ng mga sistema. Pamamagitan ng pagpapatupad ng dependency iniksyon namin turukan ng mga kinakailangang bagay handa na para gamitin (kung minsan din na tinutukoy sa pagbabaligtad ng control - IOC). Dalhin ang mga sumusunod na halimbawa:
<? Php class DecisionMaker { pampublikong function makeDecision (array $ parameter) { / / Kailangan ng database adaptor $ Dp = bagong DecisionParameters (); $ ParameterScore = $ dp-> getScore ($ parameter); / * ... Ang ilang mga karagdagang lohika desisyon ... * / bumalik ($ parameterScore> 50); } }
Ito na piraso ng code ay sinabi na maging mahigpit kaisa sa DecisionParameters object. Muling pagsusulat ng sa itaas sa isang maluwag kaisa fashion gusto namin ng isang bagay tulad ng ....
<? Php class DecisionMaker {pribadong $ _dp; pampublikong function __construct ($ dp) {$ ito-> _dp = $ dp;} pampublikong function makeDecision (array $ parameter) {$ parameterScore = $ ito-> _dp-> getScore ($ mga parameter); / * ... Ang ilang mga karagdagang lohika desisyon ... * / Bumalik ($ parameterScore> 50);}}
Habang pagkakaroon ng mga benepisyo ng maluwag kaisa code na kami ay pagdaragdag ng kumplikado tulad na ang bawat oras na ang isang bagay ay instantiated kami ay mayroon din na magbigay ng halimbawa nito ang dependencies, at ipamahagi ang mga ito sa masyadong. Halimbawa, ito:
$ Pagpili = bagong DecisionMaker (); echo $ pagpipilian-> makeDecision (array ('pagsisikap' => 'mababa', 'bumalik' => 'mataas'));
ngayon ay nagiging:
$ Dp = bagong DecisionParameters (); $ Pagpili = bagong DecisionMaker ($ dp); echo $ pagpipilian-> makeDecision (array ('pagsisikap' => 'mababa', 'bumalik' => 'mataas'));
Ang sitwasyong ito ay nagiging mas masakit na rin ang bilang ng dependensiya para sa isang klase ay nadagdagan, at kung ano kung ang dependencies may sarili dependencies? Ito ay maaaring lubos na mabilis na maging isang bagay na bangungot ng administrasyon! Ipasok lalagyan dependency iniksyon (o frameworks) ...
Dependency iniksyon lalagyan / Frameworks
Dependency iniksyon lalagyan (o frameworks) panghawakan ang proseso ng paglikha object; instantiating at injecting anumang dependencies bago bumalik ang isang halimbawa upang ang tumatawag.
Sa iyong code sa halip na lumikha ng mga bagong bagay direkta aming hiling ng isang kopya ng mga bagay mula sa mga lalagyan DI. Ang bagay na kami ay bumalik ay mayroon ng lahat ng kanyang dependencies injected at ang bagay ay handa na upang pumunta.
Symfony dependency iniksyon lalagyan
Symfony ay marahil pinakamahusay na kilala para sa kanilang buong stack MVC framework gayunman magkaroon din sila pinakawalan ng isang bilang ng mga bahagi na maaaring gamitin nang malaya. Halimbawa, ang dependency iniksyon lalagyan namin ang pagpunta sa usap tungkol dito, isang YAML parse, isang templating engine, makita ang mga bahagi Symfony para sa karagdagang.
Ang DI lalagyan Symfony ay batay sa na mula sa Spring Framework sa Java .
Bootstrapping
Upang bootstrap ang iniksyon Symfony dependency framework na ginagamit namin code bilang kasama sa ibaba. Pinili ko na gamitin YAML lamang dahil sa kanyang madaling basahin at setup. Para sa pinakamataas na bilis maaaring gusto mong isulat ang iyong mga lalagyan sa payak na PHP (ang lalagyan Symfony maaaring gawin ito para sa iyo sa sandaling setup), o Bilang kahalili cache ang buong lalagyan ng paggamit Zend_Cache , o mga katulad.
Upang i-install Symfony DI sundin ang mga tagubilin kasama dito http://components.symfony-project.org/dependency-injection/installation , at idagdag ito sa iyong landas.
/ / I-load ang lalagyan Symfony DI nangangailangan ng 'sfServiceContainerBuilder.php'; $ Lalagyan = bagong sfServiceContainerBuilder (); $ Loader = bagong sfServiceContainerLoaderFileYaml ($ lalagyan); $ Loader-> load (APPLICATION_PATH '/ config / di / services.yml'.);
Una naming magbigay ng halimbawa ng isang bagong lalagyan, at pagkatapos namin ang aming load configuration mula sa isang file YAML. Tandaan: ang DI lalagyan maaari load config mula sa ilang mga format tulad ng XML , YAML, PHP, at INI *. madalas ko na isama ang isang solong file YAML at import ng iba pang mga file mula sa loob doon.
Maraming mga configuration files ay maaring na-import paggamit ng iba't ibang mga format, ang mga mas bagong kahulugan patungan ang mga na may na tinukoy. Configuration files ay maaring isama ang mga sanggunian sa mga bagay at mga parameter.
* * * INI ay lamang makapag define ng mga parameter at hindi magawang mag-import ng ibang file
Configuration Halimbawa
angkat: - {Mapagkukunan: daos.yml} mga parameter: username: huwad mga serbisyo: # Ng Customer modelo model.customer: class: Pro_Customer tawag: - [SetLogger, [@ utils.logger]] - [SetDao, [@ data.userdata.mysql]] - [SetUserName, [% username%]] # Ng produkto modelo model.product: class: Pro_Product argumento: [% username%, {type:% accesslevel%, lastlogin:%% lastlogin}] tawag: - [SetDao, [@ data.product.mysql]] # Magtotroso utils.logger: class: Pro_Logger tagapagbuo: getInstance tawag: - [SetHandle, [@ utils.filewriter]]
tingin ko ang code sa itaas ay medyo self paliwanag ngunit para sa kaliwanagan kukunin ko ipaliwanag ang bawat bahagi na ngayon.
Una naming tukuyin ang ilang mga ini-import ng (ibig sabihin ibang file-parse), tulad ko na ang aking grupo kumpigurasyon para DAOs halimbawa sa isang file, kagamitan sa isa pang at pangalan ang file naaangkop. Habang ang isang maliit na mas mabagal ito bilis up ang pagpapanatili ng mga configuration file. Its posible rin na ma-parse ang mga file ng iba pang mga format gamit ang iba't ibang flags import. File ay ipina-parse para sa mas bagong kahulugan patungan o amending dati tinukoy serbisyo / parameters.
Susunod namin tukuyin ang isang parameter, parameter ng isang maaaring maging pangkalahatan ang anumang uri PHP variable. Sa puntong ito hindi ko alam kung ano ang aking username parameter ay dapat na (kailangan ko upang patotohanan para na!), Kaya ko na tinukoy ng isang default na halaga at kukunin ko na patungan halaga na mamaya. Tandaan, klase ay hindi instantiated hanggang hilingin mo para sa kanila kaya ng pagtukoy ng mga parameter ng isang maliit na mamaya ay ganap na ganap pagmultahin. Sumusunod na ito ako define ang ilang mga serbisyo:
- Magbigay ng halimbawa Pro_Customer, ipasa ang isang halimbawa ng aking mga magtotroso sa setLogger () method, idagdag sa aking MySQL access object data (DAO), at pumasa sa username na rin. Sa bawat oras na humingi ako para sa object na gusto ko ng bagong pagkakataon
- Lumikha ng isang halimbawa ng Pro_Product, ipasa ang mga argumento ng username at isang pagpipilian array sa constructor. Pagkatapos Instantiation tawag setDao () at ipasa ito ang aking produkto DAO
- Bigyan mo ako ng kopya ng Pro_Logger, magbigay ng halimbawa na ito gamit ang getInstance () method at pumasa sa isang kopya ng aking mga object file manunulat sa pamamagitan ng setHandle () sa sandaling ang kanyang load. Aking file manunulat ay tinukoy sa isa sa aking mga angkat.
Sa loob ng configuration files serbisyo ay isinangguni sa pamamagitan ng prepending ang pangalan sa isang @ 'simbolo', mga parameter ay isinangguni sa pamamagitan ng prepending at appending sa '%' simbolo, eg@utils.logger% username%.
Pagdaragdag ng data post loading
Minsan hindi mo alam kung ano ang halaga ng mga parameter ay dapat na hanggang matapos ang inyong bootstrapped, tulad ng sa aming mga username na parameter sa itaas. Upang patungan ang mga halaga ng offsetSet () method ay ginagamit, una makapasa sa parameter pangalan na sinusundan ng kanyang bagong halaga:
$ Lalagyan-> offsetSet ('username', $ username); Getting Bagay mula sa mga lalagyan
Minsan setup sa halip na instantiating bagay direkta kami pupunta na ngayon sa mga lalagyan DI upang makakuha ng mga pagkakataon. Sa Symfony DI tawag namin sa getService () method, pagdaan sa isang string na naglalarawan ng variable na nais mong kunin, hal
$ Magtotroso = $ lalagyan-> getService ('utils.logger'); Ito ay magsasagawa ang katumbas ng:
$ Magtotroso = Pro_Logger:: getInstance (); $ FileWriter = bagong Pro_Writer_FileWriter (); $ Magtotroso-> setHandler ($ fileWriter);
Ito ay posible na matukoy kung ang lalagyan ay isang halimbawa ng isang serbisyo sa pamamagitan ng pagtawag sa hasService () method, na nagbabalik ng isang boolean na halaga.
Its hindi kinakailangan na magkaroon ng access sa lalagyan sa kabila ng tuktok na antas ng inyong application dahil minsan kinukuha ang isang halimbawa ng lahat ng kinakailangang mga dependencies kanan pababa sa pinakamalalim na kalaliman ng iyong aplikasyon ay na-setup at naghihintay na tinatawag.
Unit Pagsubok
Dependency iniksyon rin ay may mga dagdag na benepisyo ng nagpapahintulot sa mga bagay na nasubukan sa paghihiwalay. Ang pagkuha sa mga klase halimbawa DecisionMaker bago pagpapatupad ng dependency iniksyon setup ang aming mga resulta ng pagsubok din naman ng mga umaasa sa pagpapatupad ng klase DecisionParameters.
Dapat ang klase bumalik DecisionParameters iba't ibang mga resulta ng aming mga pagsusulit ay maaaring simulan sa pamamagitan ng bagsak na walang kasalanan ng ating sarili. Paggamit ng dependency iniksyon namin ngayon pumasa sa isang DecisionParameters object na nagbabalik ng isang kilala / fixed hanay ng mga resulta para sa tiyak na mga parameter ng input, ngayon kami testing DecisionMaker sa paghihiwalay mula sa anumang mga panlabas na mga kadahilanan, ibig sabihin, kung ang aming mga pagsusuri simulan ang kabiguan na ito ay maaaring direkta maiugnay sa isang bagay pagbabago sa klase DecisionMakeer. Ito ay partikular na mahalaga na dapat ay umaasa sa data ng pagsubok mula sa isang database para sa pagsubok.
Application Configuration
Ang paraan kung saan ang iyong aplikasyon behaves sa iyong produksyon ng server ay hindi maaaring hindi iba mula sa iyong pag-unlad na setup. Halimbawa, sa isang kapaligiran sa pag-unlad ng antas ng pag-log ay marami mas detalyadong kaysa sa iyong produksyon na sistema. Sa pamamagitan ng altering ang iyong dependency iniksyon lalagyan configuration file bahagyang (o sa pag-parse ng isang karagdagang configuration file) ang altering ng pag-uugali depende sa kapaligiran ay ginawa simple.
Sa pamamagitan ng uri hinting sa mga interface sa halip na sa mga pagpapatupad kapag nagtatakda ng iyong mga dependensiya nito posible rin na swap out components para compatible component na may ilang mga linya ng YAML o XML. Halimbawa, maaari mong kasalukuyang access ang iyong database sa pamamagitan ng isang MySQL DAO (Data Access Bagay), ngunit sa oras na maaari kang bumuo ng isang PDO, Zend_Db, o doktrina implementasyon ng DAO. Sa pamamagitan ng pagdaragdag ng mga bagong pagpapatupad sa iyong configuration file na bigla ang lahat ng mga bagay na ginagamit ang lumang pagpapatupad MySQL ay ngayon gamit ang iyong bagong pagpapatupad nang hindi nangangailangan na ang atake sa tiyan ng inyong aplikasyon.
Notes
- Sa pamamagitan ng pagtatakda shared: totoo sa pagsasaayos ay palaging aming ibinigay ang parehong halimbawa ng isang bagay. Ito ay lubhang kapaki-pakinabang kapag ang pakikitungo sa mga bagay na naglalaman ng mga resources tulad ng mga koneksyon sa database, file humahawak, etc
- May mga dalawang mga pamamaraan sa pamamagitan ng na dependencies ay maaaring injected. Ang isa ay upang pumasa dependencies sa mga tagapagbuo, o Bilang kahalili pamamagitan methods setter. Sa mga pangkalahatang pattern ay na ipasa kinakailangan dependencies sa pamamagitan ng mga tagapagbuo at optionals pamamagitan setters. Ang aking sariling kagustuhan ay ang paggamit ng setters para sa lahat ng bagay, ngunit ito ay down sa mga indibidwal na mga developer
Sa wakas ....
Kasama ang isang maikling diskusyon sa dependency iniksyon at ang kanyang mga pakinabang at disadvantages na ito ay din ay isang mabilis-na-start na gabay sa pagpapatupad ng Symfony dependency iniksyon lalagyan ... sana mo na makikita na ito ay nakakagulat na mabilis at madali. Mula dito ikaw ay maaaring magsimula sa paggamit ng dependency iniksyon sa pamamagitan ng iyong application at tumingin sa paggamit ng maraming higit pa sa mga advanced na katangian (kahit na ang mga simpleng halimbawa ay sumasaklaw sa karamihan ng functionality kayo nangangailangan). Gaya ng lagi point ko kayo na ang manual para sa karagdagang impormasyon.


















































[...] Ang post na ito ay nabanggit sa nerbiyos sa pamamagitan ng Vincent Jousse, Steven Lloyd Watkin. Steven Lloyd Watkin sinabi: http://bit.ly/cUO2ov Quick start para sa symfony # dependency iniksyon framework php # # zf [...]
Mahusay na artikulo.
Mayroon akong duda ngayon. Kapag bootstrapping namin ay loading ang yaml configuration file. Kaya ay na lumikha ng mga bagay para sa lahat, na hindi namin kailangan?
Para sa halimbawa: Mayroon akong isang klase Something na kung saan ay ginagamit lamang kung minsan. Kaya ay ito ay lumilikha ng isang bagay o ito ay matalino na sapat upang i-load sa pamamagitan ng autoload function kapag ako ay pagtawag getInstance () method. hindi ko makuha na, ibig sabihin kung bakit.
Salamat
Hindi, ang klase ay lamang load kapag unang itoy kailangan.
Sa getInstance () mga halimbawa ng klase ay instantiated tulad ng:
$ Lang = Class:: getInstance ();
Kaysa sa:
$ Lang = bagong Class ();
Kadalasan ito ay ginagamit kapag ang pagpapatupad ng mga walang pareho pattern.
[...] Pagpapaalam gumamit ka ng DI sa iyong mga proyekto sa isang madaling paraan. Steven Lloyd Watkin gastusin ng kanyang oras sa pagsulat ng isang mabilis tutorial.It simulan ay nagkakahalaga na banggitin na Symfony DI lalagyan ay isang standalone library magagamit bilang isang Symfony [...]