Dependency Injection: išmoktos pamokos

32
Dependency Injection: išmoktos pamokos Gediminas Geigalas UAB Baltic Amadeus gedgei.wordpres s.com ba.lt enjoyIT.lt

Transcript of Dependency Injection: išmoktos pamokos

Page 1: Dependency Injection: išmoktos pamokos

Dependency Injection: išmoktos pamokos

Gediminas GeigalasUAB Baltic Amadeus

gedgei.wordpress.comba.lt

enjoyIT.lt

Page 2: Dependency Injection: išmoktos pamokos

Turinys

• Problemos• Sprendimai• Patarimai• Rekomenduojama

medžiaga

Page 3: Dependency Injection: išmoktos pamokos

Sąvokos

•Dependency Injection (DI) - priklausomybės perdavimas priklausančiam objektu

• IoC konteineris; konteineris – įrankis objektų ir jų priklausomybių medžiams kurti

•Composition Root (CR) – vieta, kurioje sukuriamas objektų ir jų priklausomybių medis, pvz.:•var instance = container.Resolve<T>()

Page 4: Dependency Injection: išmoktos pamokos

Programavimas be DI

Spaudžiam F5

Page 5: Dependency Injection: išmoktos pamokos

#1: DI yra naudingas

•Viešos priklausomybės•Lengvesnis perpanaudojimas•Lengvesnis testavimas•Lankstesnis gyvavimo trukmės valdymas

Page 6: Dependency Injection: išmoktos pamokos

#2: DI galimas ne visur

•Reikalaujama konstruktorių be parametrų•Nepateikiami plėtimo taškai•Pavyzdžiai:•ASP.NET WebForms Page•RoleProvider•Windows Workflow Foundation

Page 7: Dependency Injection: išmoktos pamokos

...bet norim jį naudoti

•Ką daryti, jeigu technologija nepalaiko DI?•Facade pattern•Service locator *

Page 8: Dependency Injection: išmoktos pamokos

#3: Konstruktoriai tampa dideli•Dažniausiai naudojamas constructor injection•Priklausomybių skaičius tampa didelis•Sudėtingesnis palaikymas

Page 9: Dependency Injection: išmoktos pamokos

Neprivalomos priklausomybės•Log‘inimas ir kiti cross-cutting concern•Keičiam į property injection•Local default•Null Object pattern

Page 10: Dependency Injection: išmoktos pamokos

Facade Services

•Single Responsibility Principo taikymas•Grupuoja kelias priklausomybes į vieną

Page 11: Dependency Injection: išmoktos pamokos

#4: Nenaudoti DI esybėse

•DI naudojimas esybių klasėse nerekomenduojamas•Naudoti „servisinėse“ klasėse• Jeigu esybei reikalinga service klasė, ji gali būti perduodama metodo parametrais

Page 12: Dependency Injection: išmoktos pamokos

#5: Primityvai taip pat priklausomybės

•Priklausomybė nebūtinai turi būti sudėtingas objektas•Primityvai tinkami visiems DI būdams

Page 13: Dependency Injection: išmoktos pamokos

Konfigūracijos parametrai

•Nekviesti [Web]ConfigurationManager klasių tiesiai•Priimti parametrus per konstruktorių arba property•Kūrimo/registracijos metu nuskaitomos ir panaudojamos konfigūracijos reikšmės

* CR konfigūracijos demo

Page 14: Dependency Injection: išmoktos pamokos

#6: Ne viską galima sukurti iš anksto•DI atskiria objektų kūrimą nuo jų panaudojimo•Ką daryti, jeigu objekto sukūrimas yra sudėtingas ir neturėtų būti atliekamas viso medžio kūrimo metu?•Factory pattern•Func<T>•Lazy<T>•Nepamirškite sunaikintisukurto objekto!

Page 15: Dependency Injection: išmoktos pamokos

#7: Nevisada reikalinga abstrakcija•Dažnai naudojant DI įvedamos abstrakcijos•Ar jos tikrai reikalingos?•Abstrakcijos prideda sudėtingumo•Automatiniam testavimui nebūtinos

Page 16: Dependency Injection: išmoktos pamokos

DI != DIP

•Dependency Inversion Principas:

•High level modules should not depend on low level modules – both should depend upon abstractions• Abstractions should not depend on the details. Details should depend upon abstractions.

Page 17: Dependency Injection: išmoktos pamokos

Reused Abstraction Principle

•Neįvedinėkite abstrakcijos, jeigu yra tik viena jos realizacija•Negalioja skirstant į sluoksnius

Page 18: Dependency Injection: išmoktos pamokos

#8: Kartais prireikia bendros registracijos

•Ką daryti, jeigu turim bendrą priklausomybių registraciją kelioms aplikacijoms?

Page 19: Dependency Injection: išmoktos pamokos

Bendra registracija

•Negalima talpinti registracijos kartu su priklausomybėmis tame pačiame projekte•Trys būdai:•Kopijuoti kiekvienojeaplikacijoje•Add as link•Saugoti bendrame aplikacijų lygio projekte

Page 20: Dependency Injection: išmoktos pamokos

Composition Root

•Composition Root (CR) – centrinė vieta, kurioje sukuriamas objektų medis•Gali būti tik aplikacijose, neturi būti bibliotekose•Tipinės vietos .NET programose:•Console app – Main metodas•ASP.NET MVC – IControllerFactory•WCF – IInstanceProvider, ServiceHostFactory

•Kiek CR gali būti aplikacijoje?

Page 21: Dependency Injection: išmoktos pamokos

#9: Composition Root gali būti keli

•Vienoje aplikacijoje yra keli įėjimo taškai (pvz.: ASP.NET + WCF)•Tai tarsi kelios aplikacijos vienoje•Skirtingos priklausomybės skirtinguose kontekstuose•Skirtingos gyvavimo trukmės skirtinguose kontekstuose

Page 22: Dependency Injection: išmoktos pamokos

#10: Konteineris reikalingas ne visada•DI nėra priklausomas nuo įrankių•Nereikalingas, jei:•Priklausomybių medis nedidelis•Rašoma biblioteka ar framework

Page 23: Dependency Injection: išmoktos pamokos

Kada naudoti konteinerį?

• © Mark Seeman: http://blog.ploeh.dk/2012/11/06/WhentouseaDIContainer/

Page 24: Dependency Injection: išmoktos pamokos

Varguolio DI

•Rankomis konstruojamas priklausomybių medis turi privalumų:• Paprasta ir aišku• Strong typing• Papildomas tipų tikrinimas kompiliavimo metu• Circular dependency aptikimas

Page 25: Dependency Injection: išmoktos pamokos

#11: IoC konteineris reikalingas, kai..•Dideli priklausomybių medžiai•Aspect Oriented Programming•Late binding•Lankstus gyvavimo trukmės konfigūravimas

Page 26: Dependency Injection: išmoktos pamokos

IoC konteinerio panaudojimas•Turėtų būti naudojamas tik CR:• IoC konteinerį lengva pakeisti kitu• IoC konteinerio nereikia abstrahuoti

•Nenaudokite atributų DI atlikti•Nuorodos į konteinerį turėti būti tik aukščiausiame lygmenyje (aplikacijoje)

Page 27: Dependency Injection: išmoktos pamokos

DI vs Service Location

• Jei naudoji IoC konteinerį, nereiškia, kad naudoji DI•Service Locator•CommonServiceLocator•Anti-pattern•Grąžina paslėptų priklausomybių problemą

Page 28: Dependency Injection: išmoktos pamokos

#12: Release yra LABAI svarbu•Register Resolve Release šablonas•LABAI svarbi dalis:•Tvarkingai uždaromi WCF proxy•Atlaisvinami IDisposable objektų resursai

•Pasirinkite IoC konteinerį, kuris palaiko automatinį objektų medžio naikinimą (Unity to nesugeba)

Page 29: Dependency Injection: išmoktos pamokos

Ne visi objektai yra sekami•Ką daryti su IoC konteinerio nesekamais IDisposable ir pnš. objektais?•Konteineris neseka objektų, kurių jis nesukūrė•Objektai turi būti naikinamitame kontekste, kuriamebuvo sukurti

Page 30: Dependency Injection: išmoktos pamokos

Rekomenduojama medžiaga

•Dependency Injection in .NET, Mark Seeman•http://blog.ploeh.dk/ - Mark Seeman blog‘as•http://misko.hevery.com/ - straipsniai apie testuojamą dizainą ir DI•Agile Principles, Patterns, and Practices [in C#], Robert Martin

Page 31: Dependency Injection: išmoktos pamokos

Klausimai?

Page 32: Dependency Injection: išmoktos pamokos