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>()
#1: DI yra naudingas
•Viešos priklausomybės
•Lengvesnis perpanaudojimas
•Lengvesnis testavimas
•Lankstesnis gyvavimo trukmės
valdymas
#2: DI galimas ne visur
•Reikalaujama konstruktorių be parametrų
•Nepateikiami plėtimo taškai
•Pavyzdžiai:
•ASP.NET WebForms Page
•RoleProvider
•Windows Workflow Foundation
...bet norim jį naudoti
•Ką daryti, jeigu technologija nepalaiko
DI?
•Facade pattern
•Service locator *
#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
#5: Primityvai taip pat
priklausomybės
•Priklausomybė nebūtinai turi būti
sudėtingas objektas
•Primityvai tinkami visiems DI būdams
#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 sunaikinti
sukurto objekto!
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.
#8: Kartais prireikia
bendros registracijos
•Ką daryti, jeigu turim bendrą
priklausomybių registraciją kelioms
aplikacijoms?
Bendra registracija
•Negalima talpinti registracijos kartu su
priklausomybėmis tame pačiame projekte
•Trys būdai:
•Kopijuoti kiekvienoje
aplikacijoje
•Add as link
•Saugoti bendrame aplikacijų
lygio projekte
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?
#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
#10: Konteineris
reikalingas ne visada
•DI nėra priklausomas nuo įrankių
•Nereikalingas, jei:
•Priklausomybių medis nedidelis
•Rašoma biblioteka ar framework
Varguolio DI
•Rankomis konstruojamas priklausomybių
medis turi privalumų:
• Paprasta ir aišku
• Strong typing
• Papildomas tipų tikrinimas kompiliavimo metu
• Circular dependency aptikimas
#11: IoC konteineris
reikalingas, kai..
•Dideli priklausomybių medžiai
•Aspect Oriented Programming
•Late binding
•Lankstus gyvavimo trukmės
konfigūravimas
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)
DI vs Service Location
•Jei naudoji IoC konteinerį, nereiškia, kad
naudoji DI
•Service Locator
•CommonServiceLocator
•Anti-pattern
•Grąžina paslėptų priklausomybių
problemą
#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)
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 naikinami
tame kontekste, kuriame
buvo sukurti
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