inject your dependencies
Post on 03-Jul-2015
1.838 Views
Preview:
DESCRIPTION
TRANSCRIPT
Inject Your Dependencies Inversion of control
Anže Vodovnik (anze@studiopesec.com)
Kdo sem?
• Programski arhitekt
• 10+ let izkušenj (C#, Java...)
• http://www.linkedin.com/in/avodovnik
• @avodovnik
• http://lab.studiopesec.com
Kdo je Studio Pešec?
• digital production company
• visoko-performančne, skalabilne (spletne) aplikacije
• Razvoj po meri
• Svetovanje
• Marketing
Job.ru
• 350.000+ unikatnih obiskovalcev na dan
• ASP.NET & MySQL
• 9 strežnikov
CentrSource
• ASP.NET 4 & MSSQL
• Kanada, Madžarska, Slovenija
• 120.000 unikatnih obiskovalcev + tiskan katalog
• Oglaševalska platforma za direktni marketing
Viva.si
• ASP.NET MVC & MySQL
• Netko
• 6000 dnevno unikatnih uporabnikov
• Zdravstvena skupnost
MojeDelo.com
• Vodilni zaposlitveni portal v Sloveniji
• ASP.NET 4.0 in SQL Azure
• 35.000 dnevno unikatnih obiskovalcev
• Windows Azure
Agenda
• Odvisnosti v aplikaciji
• Načrtovalski vzorci
• Dependency Injection 101
• Primeri dobrih ogrodji
• Realnost: moja aplikacija in jaz
Odvisnosti v aplikaciji• Kaj je odvisnost?• Podatkovni nivo & baze
– MySQL, MSSQL, Azure
• Poslovni nivo• Zunanje storitve & komponente• .NET framework komponente
– File objekti – Web objekti (npr. HttpContext, Request...)
Odvisnosti: pogled z vrha
BazaDALPoslovna
logikaUI
In?
• Več-nivojska arhitektura je logična ločitev
• Koda je vseeno tesno povezana in odvisna– Stranka 1: MySQL
– Stranka 2: MSSQL
– Stranka 3: Azure SQL
– Stranka N: Oracle? („$!“#?!=@„!%“!!“)} Različne verzije za vse?
In? (cnt‘d)
• Težko izoliramo posamezno komponento
– Težje testiranje
– Težje prilagajanje
– Težje vzdrževanje
– Težje spreminjanje / nadgrajevanje
Tesna sklopljenost
• Sword in Samurai sta sklopljena
• Ne moremo zamenjati oziroma dodati orožja brez spreminjanja Samurai razreda
• Vpeljemo prvi nivo abstrakcije: interface
PROGRAMMING TO AN INTERFACEREŠITEV 1
Rešitev 1
• Še vedno statična odvisnost med Samurai in Sword razredom
• Logika (Attack) ni več neposredno odvisna od implementacije
FACTORY PATTERNREŠITEV 2
Rešitev 2
• Še vedno je tesno sklopljen
• Še vedno je statična povezava
SERVICE LOCATORREŠITEV 3
Rešitev 3+ Samurai ni več statično odvisen od Sword razreda
+ Večja razširljivost, testabilnost in reusability
- Odvisno od sekvence (Assembler, Samurai)
- Težavno postavljenje (test)
- Lookup problemi?
DEPENDENCY INJECTIONREŠITEV 4
INTERFACE INJECTIONDEPENDENCY INJECTION
SETTER INJECTIONDEPENDENCY INJECTION
CONSTRUCTOR INJECTIONDEPENDENCY INJECTION
Dependency injection
• Inversion of Control = preveč generičen pojem
• Hollywood Principle
– Don’t call us, we’ll call you
• Martin Fowler predlaga: Dependency Injection
Dependency Injection
• Instanciranje na roko?
• Kaj pa povezani razredi?– new Glock(new Ammo(15, 3));
• Boilerplate koda
• Težko upravljanje (N mnogo lokacij?)
• Upravljanje z življenjskim ciklom
Dependency Injection
• Rešitev: IoC Container
• Ninject
• Spring Framework
• Unity
• StructureMap
• Castle Windsor
IoC container
• Prevzame dolgočasen del kode
IoC container
1. Get<Samurai>()
2. Obstaja mapping?
3. Reflection nad Samurai razredom1. Najde popoln konstruktor (največ „resolvable“
odvisnosti ali [Inject] atribut)
2. Najde Setterje z [Inject] atributom
4. Instancira razred & odvisnosti 1. Za vsako odvisnost pokliče .Get<Dependency>()
IoC container• V ozadju uporablja System.Reflection.Emit.DynamicMethod
• Resolva se v delegat, koda je hitrejša
• Lahko uporabite reflection (v nekaterih primerih je to občutno hitrejše)
Dependency Injection 101
• Razrešitev
– Kontekstualna ([Named(„Weak“)]
– Multiple-bindings (IEnumerable<IWeapon>)
• Upravljanje z življenjskim ciklom
– Transient, Singleton, Thread, Request (Http)
Resolution: multiple bindings
Resolution: named bindings
Resolution: več opcij• Constraints:
– Imena
– Binding Meta-podatki
– Kontekst „tarče“
– predikati
Resolution: več opcij
Upravljanje z življenjskim ciklom
• Inversion of control? AHA!
• Instanciranje po potrebi
• Dispose po potrebi
• Enostaven nadzor & menjava– Singleton | per-request | per-thread | lasten
scope
• Privzeto: InTransientScope
Upravljanje z življenjskim ciklom
• Transient .InTransientScope()
• Singleton .InSingletonScope()
• Thread .InThreadScope()
• Request .InRequestScope()
• Custom .InScope(Func<object> o)
Moduli & nalaganje
• IKernel kernel = new StandardKernel(new WeaponsModule(useMeleeWeapons));
• Kernel.Load(„*.dll“);
NINJECT & MVC 3Kako zadevo uporabiti v resničnem življenju?
DI & MVC3 = match made in heaven
• MVC3 je predstavil nov interface: IDependencyResolver
• DependencyResolver.SetResolver(new UnityDependencyResolver(container));
Zakaj?
BazaDALPoslovna
logikaUI
Zakaj?
BazaDAL„Services“Controller
Zakaj?
Kako?
• NuGet!
• Ninject.MVC3
– Ninject
– WebActivator
Ninject & MVC3
„Assembler“
Ninject & MVC3
Ninject & MVC3
Kdaj uporabiti DI?
• DI = dobra ideja skoraj vedno
• Vprašanje: ročno ali samodejno?
Ročno ali samodejno?Ročni DI Samodejno (IoC container)
Enostavno, skoraj nič učenja Konsistentnost; za večje ekipe, velik +
Nič „črne magije“ – enostavno iskanje klicev (a->b->c)
Deklerativnost: večina pravil je deklerativnih, eno mesto za opis pravil, eno mesto za spremembo teh pravil
Tudi razvijalci, ki ne razumejo DI lahko sodelujejo na projektu.
Manj tipkanja: ne rabimo se ukvarjat s pisanjem Factory razredov, ipd.
Pomaga pri testiranju! Zelo.
Povzetek
• Dependency Injection
• Bolj specifičen termin kot Inversion of Control
• IoC container rešuje mnogo problemov
• Razklopljenost modulov/servisov
Viri• http://www.martinfowler.com/articles/injection.html
• http://lab.studiopesec.com
• http://stackoverflow.com/questions/871405/why-do-i-need-an-ioc-container-as-opposed-to-straightforward-di-code
• http://ninject.org
• MSDN: Design Patterns – Dependency Injection http://msdn.microsoft.com/en-us/magazine/cc163739.aspx
Vprašanja
• http://www.studiopesec.com
• @studiopesec
• anze@studiopesec.com
top related