SlideShare a Scribd company logo
Amirkabir University of Technology (Tehran Polytechnic)- Fall 2011
Dependency Injection and Inversion
of Control
Developing flexible, reusable and testable software
Moslem Rashidi
Amirkabir University of Technology (Tehran Polytechnic)- Fall 2011
Something about the author
• This pattern was introduced in 2004 by Martin Fowler
• Martin Fowler is an author and
international speaker on software
development, specializing in object-oriented 
analysis and design, UML, patterns and
agile software development.
• In March 2000, he became Chief Scientist at ThoughtWorks, a systems
integration and consulting company.
Amirkabir University of Technology (Tehran Polytechnic)- Fall 2011
Intent
Intent of Dependency injection pattern:
It refers to the process of supplying an
external dependency to a software
component
Amirkabir University of Technology (Tehran Polytechnic)- Fall 2011
What is a “Dependency”?
Some common dependencies include:
• Application Layers
– Data Access Layer & Databases
– Business Layer
• External services & Components
– Web Services
– Third Party Components
• Framework Components
– File Objects (File.Delete(…), Directory.Exists(…))
– Web Objects (HttpContext, Session, Request, etc)
Amirkabir University of Technology (Tehran Polytechnic)- Fall 2011
Loosely Coupled Systems
• Good OO Systems – organised as web of interacting objects
• Goal – High cohesion, low coupling
• Advantages of low coupling
– Extensibility
– Testability
– Reusability
• Not so easy to achieve!
Amirkabir University of Technology (Tehran Polytechnic)- Fall 2011
A Concrete Example – A Trade Monitor
Amirkabir University of Technology (Tehran Polytechnic)- Fall 2011
Trade Monitor – The design
• TradeMonitor is coupled to LimitDao – this is not good!
– Extensibility – what if not database but distributed cache
– Testability – where do the limits for test come from?
– Reusability – logic is fairly generic . . .
public class TradeMonitor
{
private LimitDao limitDao;
public TradeMonitor()
{
limitDao = new LimitDao();
}
public bool TryTrade(string symbol, int amount)
{
int limit = limitDao.GetLimit(symbol);
int exposure = limitDao.GetExposure(symbol);
return (exposure + amount > limit) ? false : true;
}
}
public class LimitDao
{
public int GetExposure(string symbol)
{
// Do something with the database
}
public int GetLimit(string sysmbol)
{
// Do something with the database
}
}
limitDao = new LimitDao();
Amirkabir University of Technology (Tehran Polytechnic)- Fall 2011
Trade Monitor – The Design Refactored (1)
• Introduce interface/implementation separation
– Logic does not depend on DAO anymore.
– Does this really solve the problem?
public class TradeMonitor
{
private ILimitRepository limitRepository;
public TradeMonitor()
{
limitRepository = new LimitDao();
}
public bool TryTrade(string symbol, int amount)
{
. . .
}
}
public interface ILimitRepository
{
int GetExposure(string symbol);
int GetLimit(string symbol);
}
limitRepository = new LimitDao();
• The constructor still has a static dependency on DAO
Amirkabir University of Technology (Tehran Polytechnic)- Fall 2011
Trade Monitor – The Design Refactored (2)
• Introduce Factory
• TradeMonitor decoupled from LimitDao
public class LimitFactory
{
public static ILimitRepository GetLimitRepository()
{
return new LimitDao();
}
}
public class TradeMonitor
{
private ILimitRepository limitRepository;
public TradeMonitor()
{
limitRepository = LimitFactory.GetLimitRepository();
}
public bool TryTrade(string symbol, int amount)
{
. . .
}
}
LimitFactory
TradeMonitor
<<interface>>
LimitRepository
LimitDao
<<creates>>
return new LimitDao();
• LimitDao still tightly-coupled albeit to Factory
Amirkabir University of Technology (Tehran Polytechnic)- Fall 2011
Trade Monitor – The Design Refactored (3)
• Introduce ServiceLocator
• This gives us extensibility, testability, reusability
public class ServiceLocator
{
public static void RegisterService(Type type, object impl)
{. . .}
public static object GetService(Type type)
{. . .}
}
public class TradeMonitor
{
private ILimitRepository limitRepository;
public TradeMonitor()
{
object o =
ServiceLocator.GetService(typeof(ILimitRepository));
limitRepository = o as ILimitRepository;
}
public bool TryTrade(string symbol, int amount)
{
. . .
}
}
Amirkabir University of Technology (Tehran Polytechnic)- Fall 2011
ServiceLocator - Problems
• Sequence dependence
• Cumbersome setup in tests
• Service depends on infrastructure code, (ServiceLocator)
• Code needs to handle lookup problems
• Aren’t these problem minor?
Why settle for something we know has issues?
Amirkabir University of Technology (Tehran Polytechnic)- Fall 2011
A Different View
• What about adding a setter and let something else worry about creation
and resolution?
public class TradeMonitor
{
private ILimitRepository limitRepository;
public TradeMonitor()
{
}
public ILimitRepository Limits
{
set { limitRepository = value;}
}
}
• The dependencies are injected from the outside
• Components are passive and are not concerned with locating or
creating dependencies
This is Setter Dependency Injection
Amirkabir University of Technology (Tehran Polytechnic)- Fall 2011
Another Idea
• Why not just use the constructor?
public class TradeMonitor
{
private ILimitRepository limitRepository;
public TradeMonitor(ILimitRepository limitRepository)
{
this.limitRepository = limitRepository;
}
}
• No setters for dependent components, (obviously)
• 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
Amirkabir University of Technology (Tehran Polytechnic)- Fall 2011
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!
• Objects rely on their environment to provide dependencies rather than
actively obtaining them.
• Inversion of Control can make the difference between a library and a
framework.
Amirkabir University of Technology (Tehran Polytechnic)- Fall 2011
IoC Containers
• 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
Amirkabir University of Technology (Tehran Polytechnic)- Fall 2011
It Gets Better
• We can use reflection to determine dependencies – no need for config
files.
• Most IoC containers support auto-wiring.
• Make components known to container.
• Container examines constructors and determines dependencies.
• Auto-wiring provides other benefits.
• Less typing, especially long assembly names.
• Static type checking by IDE at edit time.
• More intuitive for developer.
Amirkabir University of Technology (Tehran Polytechnic)- Fall 2011
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
Amirkabir University of Technology (Tehran Polytechnic)- Fall 2011
The Solution – Test Case
[TestFixture]
public class TradeMonitorTest
{
[Test]
public void MonitorBlocksTradesWhenLimitExceeded()
{
DynamicMock mockRepository = new DynamicMock(typeof(ILimitRepository));
mockRepository.SetupResult('GetLimit', 1000000, new Type[] { typeof(string) });
mockRepository.SetupResult('GetExposure', 999999, new Type[] { typeof(string) });
TradeMonitor monitor = new TradeMonitor((ILimitRepository)mockRepository.MockInstance);
Assert.IsFalse(monitor.TryTrade('MSFT', 1000), 'Monitor should block trade');
}
}
public class TradeMonitor
{
private ILimitRepository repository;
public TradeMonitor(ILimitRepository repository) { this.repository = repository; }
public bool TryTrade(string symbol, int amount)
{
int limit = repository.GetLimit(symbol);
int exposure = repository.GetExposure(symbol);
return ((amount + exposure) <= limit);
}
}
Amirkabir University of Technology (Tehran Polytechnic)- Fall 2011
The Solution – Using the Windsor Container
• Code configuration
IWindsorContainer container = new WindsorContainer();
container.AddComponent('limitRepository', typeof(ILimitRepository), typeof(LimitDao));
container.AddComponent('tradeMonitor', typeof(TradeMonitor));
TradeMonitor monitor = (TradeMonitor)container['tradeMonitor'];
monitor.TryTrade('MSFT', 1000);
• External configuration
IWindsorContainer container = new WindsorContainer('config.xml');
TradeMonitor monitor = (TradeMonitor)container['tradeMonitor'];
monitor.TryTrade('MSFT', 1000);
<configuration>
<components>
<component id='limitRepository' service='AAABank.ILimitRepository, AAABank'
type='AAABank.LimitDao, AAABank' />
<component id='tradeMonitor' type='AAABank.TradeMonitor, AAABank' />
</components>
</configuration>
Amirkabir University of Technology (Tehran Polytechnic)- Fall 2011
The Solution – Complex Configuration
• What if components take parameters?
public class LimitDao
{
public LimitDao(string connectionString) {…}
}
public class TradeMonitor
{
public TradeMonitor(string[] monitoredSymbols) {…}
}
<configuration>
<components>
<component id='limitRepository' service='AAABank.ILimitRepository, AAABank'
type='AAABank.LimitDao, AAABank'>
<connectionString>Data Source=AServer;Initial Catalog=BankDB;User ID=sa</connectionString>
</component>
. . .
<configuration>
<components>
<component id='tradeMonitor' type='AAABank.TradeMonitor, AAABank'>
<monitoredSymbols>
<array>
<elem>MSFT</elem>
<elem>TWUK</elem>
</array>
</monitoredSymbols>
. . .
Amirkabir University of Technology (Tehran Polytechnic)- Fall 2011
Many other possibilities
• Container creates objects – but what objects?
• Can return proxy – no need for MarshalByRef inheritance.
• Object instance caching.
• Aspect Oriented Programming (concerns ,advice ,join point, pointcut).
• Remoting by configuration.
• Automatic Web Service creation.
• . . .
Amirkabir University of Technology (Tehran Polytechnic)- Fall 2011
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
Amirkabir University of Technology (Tehran Polytechnic)- Fall 2011
Questions?

More Related Content

Inversion of control

  • 1. Amirkabir University of Technology (Tehran Polytechnic)- Fall 2011 Dependency Injection and Inversion of Control Developing flexible, reusable and testable software Moslem Rashidi
  • 2. Amirkabir University of Technology (Tehran Polytechnic)- Fall 2011 Something about the author • This pattern was introduced in 2004 by Martin Fowler • Martin Fowler is an author and international speaker on software development, specializing in object-oriented  analysis and design, UML, patterns and agile software development. • In March 2000, he became Chief Scientist at ThoughtWorks, a systems integration and consulting company.
  • 3. Amirkabir University of Technology (Tehran Polytechnic)- Fall 2011 Intent Intent of Dependency injection pattern: It refers to the process of supplying an external dependency to a software component
  • 4. Amirkabir University of Technology (Tehran Polytechnic)- Fall 2011 What is a “Dependency”? Some common dependencies include: • Application Layers – Data Access Layer & Databases – Business Layer • External services & Components – Web Services – Third Party Components • Framework Components – File Objects (File.Delete(…), Directory.Exists(…)) – Web Objects (HttpContext, Session, Request, etc)
  • 5. Amirkabir University of Technology (Tehran Polytechnic)- Fall 2011 Loosely Coupled Systems • Good OO Systems – organised as web of interacting objects • Goal – High cohesion, low coupling • Advantages of low coupling – Extensibility – Testability – Reusability • Not so easy to achieve!
  • 6. Amirkabir University of Technology (Tehran Polytechnic)- Fall 2011 A Concrete Example – A Trade Monitor
  • 7. Amirkabir University of Technology (Tehran Polytechnic)- Fall 2011 Trade Monitor – The design • TradeMonitor is coupled to LimitDao – this is not good! – Extensibility – what if not database but distributed cache – Testability – where do the limits for test come from? – Reusability – logic is fairly generic . . . public class TradeMonitor { private LimitDao limitDao; public TradeMonitor() { limitDao = new LimitDao(); } public bool TryTrade(string symbol, int amount) { int limit = limitDao.GetLimit(symbol); int exposure = limitDao.GetExposure(symbol); return (exposure + amount > limit) ? false : true; } } public class LimitDao { public int GetExposure(string symbol) { // Do something with the database } public int GetLimit(string sysmbol) { // Do something with the database } } limitDao = new LimitDao();
  • 8. Amirkabir University of Technology (Tehran Polytechnic)- Fall 2011 Trade Monitor – The Design Refactored (1) • Introduce interface/implementation separation – Logic does not depend on DAO anymore. – Does this really solve the problem? public class TradeMonitor { private ILimitRepository limitRepository; public TradeMonitor() { limitRepository = new LimitDao(); } public bool TryTrade(string symbol, int amount) { . . . } } public interface ILimitRepository { int GetExposure(string symbol); int GetLimit(string symbol); } limitRepository = new LimitDao(); • The constructor still has a static dependency on DAO
  • 9. Amirkabir University of Technology (Tehran Polytechnic)- Fall 2011 Trade Monitor – The Design Refactored (2) • Introduce Factory • TradeMonitor decoupled from LimitDao public class LimitFactory { public static ILimitRepository GetLimitRepository() { return new LimitDao(); } } public class TradeMonitor { private ILimitRepository limitRepository; public TradeMonitor() { limitRepository = LimitFactory.GetLimitRepository(); } public bool TryTrade(string symbol, int amount) { . . . } } LimitFactory TradeMonitor <<interface>> LimitRepository LimitDao <<creates>> return new LimitDao(); • LimitDao still tightly-coupled albeit to Factory
  • 10. Amirkabir University of Technology (Tehran Polytechnic)- Fall 2011 Trade Monitor – The Design Refactored (3) • Introduce ServiceLocator • This gives us extensibility, testability, reusability public class ServiceLocator { public static void RegisterService(Type type, object impl) {. . .} public static object GetService(Type type) {. . .} } public class TradeMonitor { private ILimitRepository limitRepository; public TradeMonitor() { object o = ServiceLocator.GetService(typeof(ILimitRepository)); limitRepository = o as ILimitRepository; } public bool TryTrade(string symbol, int amount) { . . . } }
  • 11. Amirkabir University of Technology (Tehran Polytechnic)- Fall 2011 ServiceLocator - Problems • Sequence dependence • Cumbersome setup in tests • Service depends on infrastructure code, (ServiceLocator) • Code needs to handle lookup problems • Aren’t these problem minor? Why settle for something we know has issues?
  • 12. Amirkabir University of Technology (Tehran Polytechnic)- Fall 2011 A Different View • What about adding a setter and let something else worry about creation and resolution? public class TradeMonitor { private ILimitRepository limitRepository; public TradeMonitor() { } public ILimitRepository Limits { set { limitRepository = value;} } } • The dependencies are injected from the outside • Components are passive and are not concerned with locating or creating dependencies This is Setter Dependency Injection
  • 13. Amirkabir University of Technology (Tehran Polytechnic)- Fall 2011 Another Idea • Why not just use the constructor? public class TradeMonitor { private ILimitRepository limitRepository; public TradeMonitor(ILimitRepository limitRepository) { this.limitRepository = limitRepository; } } • No setters for dependent components, (obviously) • 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
  • 14. Amirkabir University of Technology (Tehran Polytechnic)- Fall 2011 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! • Objects rely on their environment to provide dependencies rather than actively obtaining them. • Inversion of Control can make the difference between a library and a framework.
  • 15. Amirkabir University of Technology (Tehran Polytechnic)- Fall 2011 IoC Containers • 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
  • 16. Amirkabir University of Technology (Tehran Polytechnic)- Fall 2011 It Gets Better • We can use reflection to determine dependencies – no need for config files. • Most IoC containers support auto-wiring. • Make components known to container. • Container examines constructors and determines dependencies. • Auto-wiring provides other benefits. • Less typing, especially long assembly names. • Static type checking by IDE at edit time. • More intuitive for developer.
  • 17. Amirkabir University of Technology (Tehran Polytechnic)- Fall 2011 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
  • 18. Amirkabir University of Technology (Tehran Polytechnic)- Fall 2011 The Solution – Test Case [TestFixture] public class TradeMonitorTest { [Test] public void MonitorBlocksTradesWhenLimitExceeded() { DynamicMock mockRepository = new DynamicMock(typeof(ILimitRepository)); mockRepository.SetupResult('GetLimit', 1000000, new Type[] { typeof(string) }); mockRepository.SetupResult('GetExposure', 999999, new Type[] { typeof(string) }); TradeMonitor monitor = new TradeMonitor((ILimitRepository)mockRepository.MockInstance); Assert.IsFalse(monitor.TryTrade('MSFT', 1000), 'Monitor should block trade'); } } public class TradeMonitor { private ILimitRepository repository; public TradeMonitor(ILimitRepository repository) { this.repository = repository; } public bool TryTrade(string symbol, int amount) { int limit = repository.GetLimit(symbol); int exposure = repository.GetExposure(symbol); return ((amount + exposure) <= limit); } }
  • 19. Amirkabir University of Technology (Tehran Polytechnic)- Fall 2011 The Solution – Using the Windsor Container • Code configuration IWindsorContainer container = new WindsorContainer(); container.AddComponent('limitRepository', typeof(ILimitRepository), typeof(LimitDao)); container.AddComponent('tradeMonitor', typeof(TradeMonitor)); TradeMonitor monitor = (TradeMonitor)container['tradeMonitor']; monitor.TryTrade('MSFT', 1000); • External configuration IWindsorContainer container = new WindsorContainer('config.xml'); TradeMonitor monitor = (TradeMonitor)container['tradeMonitor']; monitor.TryTrade('MSFT', 1000); <configuration> <components> <component id='limitRepository' service='AAABank.ILimitRepository, AAABank' type='AAABank.LimitDao, AAABank' /> <component id='tradeMonitor' type='AAABank.TradeMonitor, AAABank' /> </components> </configuration>
  • 20. Amirkabir University of Technology (Tehran Polytechnic)- Fall 2011 The Solution – Complex Configuration • What if components take parameters? public class LimitDao { public LimitDao(string connectionString) {…} } public class TradeMonitor { public TradeMonitor(string[] monitoredSymbols) {…} } <configuration> <components> <component id='limitRepository' service='AAABank.ILimitRepository, AAABank' type='AAABank.LimitDao, AAABank'> <connectionString>Data Source=AServer;Initial Catalog=BankDB;User ID=sa</connectionString> </component> . . . <configuration> <components> <component id='tradeMonitor' type='AAABank.TradeMonitor, AAABank'> <monitoredSymbols> <array> <elem>MSFT</elem> <elem>TWUK</elem> </array> </monitoredSymbols> . . .
  • 21. Amirkabir University of Technology (Tehran Polytechnic)- Fall 2011 Many other possibilities • Container creates objects – but what objects? • Can return proxy – no need for MarshalByRef inheritance. • Object instance caching. • Aspect Oriented Programming (concerns ,advice ,join point, pointcut). • Remoting by configuration. • Automatic Web Service creation. • . . .
  • 22. Amirkabir University of Technology (Tehran Polytechnic)- Fall 2011 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
  • 23. Amirkabir University of Technology (Tehran Polytechnic)- Fall 2011 Questions?