MS FEST 2012DI v .NET bez pověr, iluzí a  frikulínského nadšení            René Stein       http://renestein.net   http://...
Na této přednášce nebude pomlouvánoMetro (ani kdyby se jmenovalo Modern UI)!
Pracujeme se závislostmi - v        aplikacích• A rovnou se na takovou aplikaci  podíváme (bez pomoci Karla  Nešpora)
Každý problém se závislostmi              vyřeší on!        Náš chrabrý Singleton!   Bůh je stejně jako singleton vždy jen...
Singleton v aplikaci• Ukázka singletonu• Ukázka komplikovanějšího singletonu  složeného z dalších singletonů –  SimpleServ...
Singleton(y)Poskytuje globální přístupový bod k  jedné instanci.Ale:• Skryté závislosti v kódu aplikace.• Malá kontrola na...
Repozitář služeb• Vulgo „service locator“• Nabízí „služby všeho druhu“• Redukuje větší množství singletonů  v aplikaci na ...
Repozitář služeb - nevýhodyObjekt, který ve svém rozhraní slibuje víc, nežmůže splnit.Ve svém rozhraní nabízí všechny služ...
Repozitář služeb – nevýhody IINepřehledný kód  SimpleServiceRepository.Instance.GetSer  vice<X> - to je všudypřítomná náhr...
Repozitář služeb – nevýhody             III• Nikdy se nemůžete spolehnout na  to, že služba je repozitáři  registrována.• ...
Dependency injection  Odstranění skrytých   Odstranění těsných       závislostí       vazeb mezi objekty   (Snadné) mapová...
Injektování přes             konstruktorvar myOrderService = new OrderService (myRepository);class OrderService{   public ...
Injektujeme přes konstruktor   Předávání závislostí, bez   kterých instance nemůže   existovat
Injektujeme přes vlastnostpublic class ExportService{    public ExportService()     {         ConfigService = new DefaultC...
Kdy injektovat přes          vlastnost?Když je závislost nepovinná. Ale pozorna NullReferenceException připoužívání závisl...
Pozor na problémy sautomatickým injektováním  závislostí přes vlastnosti                        //ViewModelBaseinterface I...
Injektování přes argument         metodypublic void RunTransition   (IWorkflowContext context){  if(context == null)      ...
Kdy injektovat přes    argument metodyPři každém volání metody potřebujemeodlišný objektPředávaný objekt většinou představ...
DI kontajnerDI kontajner si představme jakonástroj, který nám zjednodušujevytváření objektových grafů.Jako nástroj, pomocí...
Co očekávat od DI      kontajneru? SOLIDní           Správa životního cyklu                        služeb, resp.kompozice ...
Použití DI kontajneru – 3 R           RegisterR =Registrace      Jednorázová registrace abstrakcí      na implementace (re...
R = registrace• Preferujte konfiguraci v kódu.m_container.Register( Component.For(typeof(IRepository<>)) .ImplementedBy(ty...
Registrace v XML – CastleWindsor („pluginy – pozdnívazba “)<components> <component   id= "MyLogService"   service=  "Commo...
R = Registrace - další     doporučeníPreferujte hromadnéregistrace s využitímkonvencí místoexplicitní registracekaždé služby
Registrace na základě             jmenných konvencíPredicate<Type> servicesCondition = type =>  type.Name.Contains(PROVIDE...
Použití DI kontajneru – 3 R          ResolveR = Resolve          Získání služby z DI      kontajneru. Službu mohu         ...
Princip neviditelnosti DI               kontajneruNikdy nepodlehněte pokušení používat DI kontajner jako servicelocator (r...
DI kontajner není service                              locator!public MainViewModel                public MainViewModel(IW...
Abstraktní továrna ve      Windsor Castlu• Castle dokáže typické abstraktní  továrny generovat sám s využitím  dynamické p...
Použití DI kontajneru – 3 R                  Release• Cokoli vyzvednu „manuálně“ z DI kontajneru   (Resolve) uvolním metod...
Mýty o dependencyinjection (a IoC)  DI je komplikovaná záležitost .(A já jsem duše                    prostá )     Nepíšu ...
Mýty o dependency            injection• V konstruktoru se mi budou množit  argumenty => jednoduchý detektor  porušení SRP....
DI kontajnery v .Net světěCastle Windsor       Ninject                   Hiro     Autofac       StructureMap          Unit...
DI kontajnery – podobnosti         a rozdílySvatou DI trojici Register/Resolve/Releasezvládne každý DI kontajner.Pak má al...
René Stein• Vývoj aplikací, veřejné a inhouse kurzy• http://www.renestein.net/nabidka.aspxhttp://blog.renestein.nethttp://...
Dependency injection v .Net Frameworku
Upcoming SlideShare
Loading in …5
×

Dependency injection v .Net Frameworku

9,587 views

Published on

Dependency injection v .Net bez pověr, iluzí a frikulínského nadšení.

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
9,587
On SlideShare
0
From Embeds
0
Number of Embeds
8,354
Actions
Shares
0
Downloads
7
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Dependency injection v .Net Frameworku

  1. 1. MS FEST 2012DI v .NET bez pověr, iluzí a frikulínského nadšení René Stein http://renestein.net http://twitter.com/renestein
  2. 2. Na této přednášce nebude pomlouvánoMetro (ani kdyby se jmenovalo Modern UI)!
  3. 3. Pracujeme se závislostmi - v aplikacích• A rovnou se na takovou aplikaci podíváme (bez pomoci Karla Nešpora)
  4. 4. Každý problém se závislostmi vyřeší on! Náš chrabrý Singleton! Bůh je stejně jako singleton vždy jenjeden. Skeptická poznámka: dokud nejsou oba minimálně trojjediní.
  5. 5. Singleton v aplikaci• Ukázka singletonu• Ukázka komplikovanějšího singletonu složeného z dalších singletonů – SimpleServiceHolder.
  6. 6. Singleton(y)Poskytuje globální přístupový bod k jedné instanci.Ale:• Skryté závislosti v kódu aplikace.• Malá kontrola nad životním cyklem singletonu (jen ta „lazy“ inicializace).• Problémy se singletony ve vícevláknovém prostředí.• Problémy se singletony v unit testech.
  7. 7. Repozitář služeb• Vulgo „service locator“• Nabízí „služby všeho druhu“• Redukuje větší množství singletonů v aplikaci na jeden singleton
  8. 8. Repozitář služeb - nevýhodyObjekt, který ve svém rozhraní slibuje víc, nežmůže splnit.Ve svém rozhraní nabízí všechny služby na světě(a možná i mimo něj).Závislosti třídy nepoznáme z jejíhorozhraní, protože komunikace s repozitářemslužeb je utopena v privátní implementaci třídy.
  9. 9. Repozitář služeb – nevýhody IINepřehledný kód SimpleServiceRepository.Instance.GetSer vice<X> - to je všudypřítomná náhrada za volání konstruktoru - new X().SimpleServiceRepository.Instance.GetServic e< ….>• Všechny knihovny většinou závisí na knihovně s SimpleServiceRepository.
  10. 10. Repozitář služeb – nevýhody III• Nikdy se nemůžete spolehnout na to, že služba je repozitáři registrována.• Víte, co je „Ambient context“?var errService = SimpleServiceRepository.Instance.GetService<IWorkflowE rrorInfoProviderEx>(); - na jiném místěif(errService != null){ errService.PublishError(….);}
  11. 11. Dependency injection Odstranění skrytých Odstranění těsných závislostí vazeb mezi objekty (Snadné) mapování Spolupráce objektů s abstrakcí na přesně vymezenou implementaci odpovědností (SRP)
  12. 12. Injektování přes konstruktorvar myOrderService = new OrderService (myRepository);class OrderService{ public OrderService(IRepository<Order> repository) { if(repository == null) { throw ….; } m_repository = repository; }….}
  13. 13. Injektujeme přes konstruktor Předávání závislostí, bez kterých instance nemůže existovat
  14. 14. Injektujeme přes vlastnostpublic class ExportService{ public ExportService() { ConfigService = new DefaultConfigService(); } public IConfigService ConfigService { get; set; } public void ExportData { …. ConfigService.GetValue(…); }}
  15. 15. Kdy injektovat přes vlastnost?Když je závislost nepovinná. Ale pozorna NullReferenceException připoužívání závislosti!Když máte smysluplnou výchozíimplementaci (i Null object) => ve tříděse ale svážeme s další konkrétní třídou(new (konkrétní) ZavislostX())
  16. 16. Pozor na problémy sautomatickým injektováním závislostí přes vlastnosti //ViewModelBaseinterface IViewModel { [DoNotWire] IView CurrentView public IView { CurrentView get; { } get; } set; }
  17. 17. Injektování přes argument metodypublic void RunTransition (IWorkflowContext context){ if(context == null) { throw ….; } …context.ApplyTransitionRules(currentState, this);
  18. 18. Kdy injektovat přes argument metodyPři každém volání metody potřebujemeodlišný objektPředávaný objekt většinou představujeunikátní kontext jednoho volání metodyS tímto druhem závislostí nám DIkontajner nepomůže
  19. 19. DI kontajnerDI kontajner si představme jakonástroj, který nám zjednodušujevytváření objektových grafů.Jako nástroj, pomocí kterého snadnopropojíme nezávislé části naší aplikace asplníme jim jejich přání = dodáme jimvšechny jejich závislosti.
  20. 20. Co očekávat od DI kontajneru? SOLIDní Správa životního cyklu služeb, resp.kompozice komponent objektů (Singleton, PerThread, PerWebRequest, Transi ent) Intercepce metod (skvělá podpora návrhového vzoru Decorator)
  21. 21. Použití DI kontajneru – 3 R RegisterR =Registrace Jednorázová registrace abstrakcí na implementace (registrace komponent a služeb) v takzvaném „DI kompozičním centru “ (composition root) po startu aplikace.
  22. 22. R = registrace• Preferujte konfiguraci v kódu.m_container.Register( Component.For(typeof(IRepository<>)) .ImplementedBy(typeof(DefaultEFRepository<>)));• Registrace v XML konfiguračním souboru jen tehdy, když chcete přidávat „pluginy“.
  23. 23. Registrace v XML – CastleWindsor („pluginy – pozdnívazba “)<components> <component id= "MyLogService" service= "CommonServices.ILogger, CommonServic es" type="DefaultServices.DbLogger, DefaultS ervices" </component></components>
  24. 24. R = Registrace - další doporučeníPreferujte hromadnéregistrace s využitímkonvencí místoexplicitní registracekaždé služby
  25. 25. Registrace na základě jmenných konvencíPredicate<Type> servicesCondition = type => type.Name.Contains(PROVIDER_SUFFIX) || type.Name.Contains(SERVICE_SUFFIX); m_container.Register(Classes.FromAssembly. Containing(typeof(INewObjectIdProvider<>)) .Where(servicesCondition) .WithServiceDefaultInterfaces() .WithServiceSelf() .LifestyleSingleton());
  26. 26. Použití DI kontajneru – 3 R ResolveR = Resolve Získání služby z DI kontajneru. Službu mohu ihned používat, její závislosti splnil DI kontajner ALE:
  27. 27. Princip neviditelnosti DI kontajneruNikdy nepodlehněte pokušení používat DI kontajner jako servicelocator (repozitář služeb).Metodu „Resolve“ na DI kontajneru volá jen „composition root“a infrastrukturní objekty (ControllerFactory v ukázce).Nikdy se ve svém aplikačním kódu nereferencujte DI kontajner.K tomu vám dopomáhej zdravý vývojářský úsudek a vzorAbstract Factory.
  28. 28. DI kontajner není service locator!public MainViewModel public MainViewModel(IWindsorContainer container) (IViewFactory viewfactory){ { …. ….} }var childView = var childView = container.Resolve<IChildView>; viewfactory.Create<IChildView>();
  29. 29. Abstraktní továrna ve Windsor Castlu• Castle dokáže typické abstraktní továrny generovat sám s využitím dynamické proxy.m_container.AddFacility<TypedFactory Facility>();m_container.Register(Component.For<I ViewFactory>().AsFactory<IViewFact ory>());
  30. 30. Použití DI kontajneru – 3 R Release• Cokoli vyzvednu „manuálně“ z DI kontajneru (Resolve) uvolním metodou Release.public override void ReleaseController(IController controller){ m_container.Release(controller); base.ReleaseController(controller); }• Životní cyklus služeb řídí DI kontajner.
  31. 31. Mýty o dependencyinjection (a IoC) DI je komplikovaná záležitost .(A já jsem duše prostá ) Nepíšu unit testy (!) => nepotřebuju DIKdo nepoužívá DI (nebo o ní alespoň nemluví) není pravý vývojář DI == DI kontajner Říká se tomu DI kontajner, ale já vím, že je to jen vylepšená abstraktní továrna
  32. 32. Mýty o dependency injection• V konstruktoru se mi budou množit argumenty => jednoduchý detektor porušení SRP.public GodService(IWorldBuilder worldbuilder,IHelloWorld initWorldService,IEdenService edenService,IJesusChristSupport jesusSupportServiceIApocalypseRunner apocalypseRunner)• Víte, co jsou kompozitní služby?
  33. 33. DI kontajnery v .Net světěCastle Windsor Ninject Hiro Autofac StructureMap Unity ?MEF? Spring.NET
  34. 34. DI kontajnery – podobnosti a rozdílySvatou DI trojici Register/Resolve/Releasezvládne každý DI kontajner.Pak má ale každý kontajner své unikátnívlastnosti –Windsor Castle vyniká při intercepcipomocí dynamické proxy nebo se s jeho pomocískvěle diagnostikují chyby při registraci služeb…
  35. 35. René Stein• Vývoj aplikací, veřejné a inhouse kurzy• http://www.renestein.net/nabidka.aspxhttp://blog.renestein.nethttp://twitter.com/renestein

×