Inversion of Control and Dependency Injection
-
Upload
andriy-buday -
Category
Technology
-
view
1.682 -
download
2
description
Transcript of Inversion of Control and Dependency Injection
Inversion of Control andDependency Injection,StructureMap
Andriy Buday
2
Loosely Coupled Systems
Copyright © 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…
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.
7Copyright © 2009 SoftServe, Inc.
Another IdeaWhy 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
8Copyright © 2009 SoftServe, Inc.
Practice: ServiceLocator
Let us see code, we talked about
Let us implement something new and great
9
MusicPlayer – Introducing Service LocatorIntroduce 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.
10Copyright © 2009 SoftServe, Inc.
ServiceLocator - Problems
Sequence dependence
Cumbersome setup in tests
Code needs to handle lookup problems
11Copyright © 2009 SoftServe, Inc.
What about Inversion of Control?
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
12Copyright © 2009 SoftServe, Inc.
IoC ContainersThere 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
13Copyright © 2009 SoftServe, Inc.
IoC Containers and Features
Container Setter DI
Ctor DI
External config
Code config
Auto-wiring
Lifecycle support`
Url
System.ComponentModel a a Part of .Net framework
PicoContainer.Net a a a a a http://picocontainer.org
Windsor a a a ? a http://www.castleproject.org
StructureMap a a a P a http://sourceforge.net/projects/structuremap
Spring.Net a a a ? a a http://www.springframework.net/
ObjectBuilder a a a a ?? a http://msdn.microsoft.com
?? = More investigation
? = Setter based DI required for primitive dependencies
P = Partial still requires configuration to point to assemblies to scan
14Copyright © 2009 SoftServe, Inc.
Practice:StructureMap - from easy to advanced
Refactor MusicPlayer
Consumer and Soda example
• config file configuration
•fluent configuraion
Auto-wiring
15Copyright © 2009 SoftServe, Inc.
Practice: StructureMap: Link project examples
As we use this on Link project…
16Copyright © 2009 SoftServe, Inc.
Summary
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.
18Copyright © 2009 SoftServe, Inc.
Some links:
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