Inversion of Control and Dependency Injection, StructureMap Andriy Buday
Loosely Coupled Systems Copyright  ©  2009 SoftServe, Inc.
A Concrete Example – A Music Player As a User of Music Player I want my Player to select songs of my favorite band from some list and play  those songs… Copyright  ©  2009 SoftServe, Inc.
Music Player – The design Music Player is coupled to SongFinder – this is not good! Extensibility – what if not database but distributed cache Testability – where do the songs for test come from? Reusability – logic is fairly generic . . .  public class MusicPlayer { private SongFinder songFinder; public MusicPlayer() { songFinder = new SongFinder(); } public Song[] GetBandSongs(String band) { var allsongs = songFinder.FindAllSongs(); return allsongs   .Where(x => x.Band == band).ToArray(); } } public class SongFinder { public virtual Song[] FindAllSongs() { var musStorage = new MusicStorage(); return musStorage.SONGS; } } Copyright  ©  2009 SoftServe, Inc.
Music Player – Introducing Interface  Introduce interface/implementation separation Logic does not depend on SongFinder anymore. Does this really solve the problem? The constructor still has a static dependency on SongFinder public interface ISongFinder      {           Song[] FindAllSongs();       } private ISongFinder songFinder;       public MusicPlayer()       {           songFinder = new SongFinder();       } public Song[] GetBandSongs(String band) { var allsongs = songFinder.FindAllSongs(); return allsongs   .Where(x => x.Band == band).ToArray(); } Copyright  ©  2009 SoftServe, Inc.
Music Player – Introducing Factory Introduce Factory MusicPlayer decoupled from SongFinder      public class SongFinderFactory     {         public ISongFinder GiveUsDatabaseSongFinder()         {             return new SongFinder();         }     }      public MusicPlayer()     {        songFinder = SongFinderFactory.GiveUsDatabaseSongFinder();     } Copyright  ©  2009 SoftServe, Inc.
Another Idea Copyright  ©  2009 SoftServe, Inc. Why not just use the constructor? public class MusicPlayer { private ISongFinder m_songFinder; public MusicPlayer(ISongFinder songFinder) { m_songFinder = songFinder; } } One-shot initialisation – components are always initialised correctly All dependencies are clearly visible from code It is impossible to create cyclic dependencies This is  Constructor   Dependency Injection
Practice: ServiceLocator Copyright  ©  2009 SoftServe, Inc. Let us see code, we talked about Let us implement something new and great
MusicPlayer – Introducing Service Locator Introduce ServiceLocator This gives us extensibility, testability, reusability public static class ServiceLocator {     public static void RegisterService(Type type, Object impl)     { …     }     public static Object GetService(Type type)     { …     } }  public MusicPlayer() {    var fiderService = ServiceLocator.GetService(typeof (ISongFinder));    songFinder = (ISongFinder)fiderService; } Copyright  ©  2009 SoftServe, Inc.
ServiceLocator - Problems Copyright  ©  2009 SoftServe, Inc. Sequence dependence Cumbersome setup in tests Code needs to handle lookup problems
What about Inversion of Control? Copyright  ©  2009 SoftServe, Inc. Dependency Injection - one example of IoC design principle Also known as the Hollywood Principle Don’t call us, we’ll call you! Inversion of Control can make the difference between a library and a framework
IoC Containers Copyright  ©  2009 SoftServe, Inc. There are still some open questions Who creates the dependencies? What if we need some initialisation code that must be run after dependencies have been set? What happens when we don’t have all the components? IoC Containers solve these issues Have configuration – often external Create objects Ensure all dependencies are satisfied Provide lifecycle support
IoC Containers and Features Copyright  ©  2009 SoftServe, Inc.
Practice: StructureMap - from easy to advanced Copyright  ©  2009 SoftServe, Inc. Refactor MusicPlayer Consumer and Soda example config file configuration fluent configuraion Auto-wiring
Practice:  StructureMap: Link project examples Copyright  ©  2009 SoftServe, Inc. As we use this on Link project…
Summary Copyright  ©  2009 SoftServe, Inc. Container based DI facilitates: Testability Extensibility Reusability Makes the difference between framework and library Not just use but extend Essential for complex Domain Driven Design Easier to separate 'infrastructure' from business logic We took a look on StructureMap IoC container Also took a look on our product code usage of StructureMap
Questions? Copyright  ©  2009 SoftServe, Inc.
Some links: Copyright  ©  2009 SoftServe, Inc. My article: http:// andriybuday.blogspot.com/2009/10/inversion-of-control.html StructureMap site: http:// structuremap.sourceforge.net/Default.htm MartinFlower article: http:// martinfowler.com/articles/injection.html Derik Whittaker IoC dev movies: http:// dimecasts.net/Casts/ByTag/IoC

Inversion of Control and Dependency Injection

  • 1.
    Inversion of Controland Dependency Injection, StructureMap Andriy Buday
  • 2.
    Loosely Coupled SystemsCopyright © 2009 SoftServe, Inc.
  • 3.
    A Concrete Example– A Music Player As a User of Music Player I want my Player to select songs of my favorite band from some list and play those songs… Copyright © 2009 SoftServe, Inc.
  • 4.
    Music Player –The design Music Player is coupled to SongFinder – this is not good! Extensibility – what if not database but distributed cache Testability – where do the songs for test come from? Reusability – logic is fairly generic . . . public class MusicPlayer { private SongFinder songFinder; public MusicPlayer() { songFinder = new SongFinder(); } public Song[] GetBandSongs(String band) { var allsongs = songFinder.FindAllSongs(); return allsongs .Where(x => x.Band == band).ToArray(); } } public class SongFinder { public virtual Song[] FindAllSongs() { var musStorage = new MusicStorage(); return musStorage.SONGS; } } Copyright © 2009 SoftServe, Inc.
  • 5.
    Music Player –Introducing Interface Introduce interface/implementation separation Logic does not depend on SongFinder anymore. Does this really solve the problem? The constructor still has a static dependency on SongFinder public interface ISongFinder     {          Song[] FindAllSongs();     } private ISongFinder songFinder;       public MusicPlayer()       {           songFinder = new SongFinder();       } public Song[] GetBandSongs(String band) { var allsongs = songFinder.FindAllSongs(); return allsongs .Where(x => x.Band == band).ToArray(); } Copyright © 2009 SoftServe, Inc.
  • 6.
    Music Player –Introducing Factory Introduce Factory MusicPlayer decoupled from SongFinder     public class SongFinderFactory     {         public ISongFinder GiveUsDatabaseSongFinder()         {             return new SongFinder();         }     }      public MusicPlayer()     {        songFinder = SongFinderFactory.GiveUsDatabaseSongFinder();     } Copyright © 2009 SoftServe, Inc.
  • 7.
    Another Idea Copyright © 2009 SoftServe, Inc. Why not just use the constructor? public class MusicPlayer { private ISongFinder m_songFinder; public MusicPlayer(ISongFinder songFinder) { m_songFinder = songFinder; } } One-shot initialisation – components are always initialised correctly All dependencies are clearly visible from code It is impossible to create cyclic dependencies This is Constructor Dependency Injection
  • 8.
    Practice: ServiceLocator Copyright © 2009 SoftServe, Inc. Let us see code, we talked about Let us implement something new and great
  • 9.
    MusicPlayer – IntroducingService Locator Introduce ServiceLocator This gives us extensibility, testability, reusability public static class ServiceLocator {     public static void RegisterService(Type type, Object impl)     { …     }     public static Object GetService(Type type)     { …     } } public MusicPlayer() {    var fiderService = ServiceLocator.GetService(typeof (ISongFinder));    songFinder = (ISongFinder)fiderService; } Copyright © 2009 SoftServe, Inc.
  • 10.
    ServiceLocator - ProblemsCopyright © 2009 SoftServe, Inc. Sequence dependence Cumbersome setup in tests Code needs to handle lookup problems
  • 11.
    What about Inversionof Control? Copyright © 2009 SoftServe, Inc. Dependency Injection - one example of IoC design principle Also known as the Hollywood Principle Don’t call us, we’ll call you! Inversion of Control can make the difference between a library and a framework
  • 12.
    IoC Containers Copyright © 2009 SoftServe, Inc. There are still some open questions Who creates the dependencies? What if we need some initialisation code that must be run after dependencies have been set? What happens when we don’t have all the components? IoC Containers solve these issues Have configuration – often external Create objects Ensure all dependencies are satisfied Provide lifecycle support
  • 13.
    IoC Containers andFeatures Copyright © 2009 SoftServe, Inc.
  • 14.
    Practice: StructureMap -from easy to advanced Copyright © 2009 SoftServe, Inc. Refactor MusicPlayer Consumer and Soda example config file configuration fluent configuraion Auto-wiring
  • 15.
    Practice: StructureMap:Link project examples Copyright © 2009 SoftServe, Inc. As we use this on Link project…
  • 16.
    Summary Copyright © 2009 SoftServe, Inc. Container based DI facilitates: Testability Extensibility Reusability Makes the difference between framework and library Not just use but extend Essential for complex Domain Driven Design Easier to separate 'infrastructure' from business logic We took a look on StructureMap IoC container Also took a look on our product code usage of StructureMap
  • 17.
    Questions? Copyright © 2009 SoftServe, Inc.
  • 18.
    Some links: Copyright © 2009 SoftServe, Inc. My article: http:// andriybuday.blogspot.com/2009/10/inversion-of-control.html StructureMap site: http:// structuremap.sourceforge.net/Default.htm MartinFlower article: http:// martinfowler.com/articles/injection.html Derik Whittaker IoC dev movies: http:// dimecasts.net/Casts/ByTag/IoC