Your SlideShare is downloading. ×
  • Like
Dependency injection v .Net Frameworku
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Now you can save presentations on your phone or tablet

Available for both IPhone and Android

Text the download link to your phone

Standard text messaging rates apply

Dependency injection v .Net Frameworku

  • 8,568 views
Published

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

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

Published in Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
8,568
On SlideShare
0
From Embeds
0
Number of Embeds
8

Actions

Shares
Downloads
4
Comments
0
Likes
0

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 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. Na této přednášce nebude pomlouvánoMetro (ani kdyby se jmenovalo Modern UI)!
  • 3. Pracujeme se závislostmi - v aplikacích• A rovnou se na takovou aplikaci podíváme (bez pomoci Karla Nešpora)
  • 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. Singleton v aplikaci• Ukázka singletonu• Ukázka komplikovanějšího singletonu složeného z dalších singletonů – SimpleServiceHolder.
  • 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. 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. 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. 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. 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. 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. Injektování přes konstruktorvar myOrderService = new OrderService (myRepository);class OrderService{ public OrderService(IRepository<Order> repository) { if(repository == null) { throw ….; } m_repository = repository; }….}
  • 13. Injektujeme přes konstruktor Předávání závislostí, bez kterých instance nemůže existovat
  • 14. Injektujeme přes vlastnostpublic class ExportService{ public ExportService() { ConfigService = new DefaultConfigService(); } public IConfigService ConfigService { get; set; } public void ExportData { …. ConfigService.GetValue(…); }}
  • 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. 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. Injektování přes argument metodypublic void RunTransition (IWorkflowContext context){ if(context == null) { throw ….; } …context.ApplyTransitionRules(currentState, this);
  • 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. 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. 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. 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. 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. Registrace v XML – CastleWindsor („pluginy – pozdnívazba “)<components> <component id= "MyLogService" service= "CommonServices.ILogger, CommonServic es" type="DefaultServices.DbLogger, DefaultS ervices" </component></components>
  • 24. R = Registrace - další doporučeníPreferujte hromadnéregistrace s využitímkonvencí místoexplicitní registracekaždé služby
  • 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. 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. 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. DI kontajner není service locator!public MainViewModel public MainViewModel(IWindsorContainer container) (IViewFactory viewfactory){ { …. ….} }var childView = var childView = container.Resolve<IChildView>; viewfactory.Create<IChildView>();
  • 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. 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. 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. 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. DI kontajnery v .Net světěCastle Windsor Ninject Hiro Autofac StructureMap Unity ?MEF? Spring.NET
  • 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. René Stein• Vývoj aplikací, veřejné a inhouse kurzy• http://www.renestein.net/nabidka.aspxhttp://blog.renestein.nethttp://twitter.com/renestein