Title: Dependency Injection What, Why and How
1Dependency InjectionWhat, Why and How
- Peter Provost
- peter.provost_at_microsoft.com
- http//www.peterprovost.org/
- Slides will be here
Brad Wilson bradwils_at_microsoft.com http//agilepro
grammer.com/dotnetguy
2What is Dependency Injection?
- DI is all about wiring up objects
- Come on, that isnt hard. Weve been doing that
for years!
3A Real World Example?
Web App
Stock Quotes
Authenticator
Error Handler
Logger
Database
This example was originally created by Jim
Weirich in Ruby on his blog. See his original
article at http//onestepback.org/index.cgi/Tech/R
uby/DependencyInjectionInRuby.rdoc
4The Old Way
- public class WebApp
-
- public WebApp()
-
- quotes new StockQuotes()
- authenticator new Authenticator()
- database new Database()
- logger new Logger()
- errorHandler new ErrorHandler()
-
- // More code here...
5What about the child objects?
- How does the StockQuotes find the Logger?
- How does the Authenticator find the database?
- Etc.?
- Suppose you want to use a TestingLogger instead?
Or a MockDatabase?
6Service Locator Interface
- public interface ILocator
-
- TObject GetltTObjectgt()
7Service Locator Example
- public class MyLocator ILocator
-
- protected DictionaryltType, objectgt dict new
DictionaryltType,objectgt() - public MyLocator()
-
- dict.Add(typeof(ILogger), new Logger())
- dict.Add(typeof(IErrorHandler), new
ErrorHandler(this)) - dict.Add(typeof(IQuotes), new StockQuotes(this))
- dict.Add(typeof(IDatabase), new Database(this))
- dict.Add(typeof(IAuthenticator), new
Authenticator(this)) - dict.Add(typeof(WebApp), new WebApp(this))
-
8StockQuotes with Locator
- public class StockQuotes
-
- public StockQuotes(ILocator locator)
-
- errorHandler locator.GetltIErrorHandlergt()
- logger locator.GetltILoggergt()
-
- // More code here...
9Good things
- Classes are decoupled from explicit imlementation
types - Easy to externalize the config
10Bad things
- Everyone takes a dependency on the ILocator
- Hard to store constants and other useful
primitives - Creation order is still a problem
11Dependency Injection Containers
- Gets rid of the dependency on the ILocator
- Object is no longer responsible for finding its
dependencies - The container does it for you
12Then what?
- Write your objects the way you want
- Setup the container
- Ask the container for objects
- The container creates objects for you and
fulfills dependencies
13Setting Up the Container (Code)
- DIContainer container new DIContainer()
- container.RegisterltILogger, Loggergt()
- container.RegisterltIDatabase, Databasegt()
- container.RegisterltIErrorHandler,
ErrorHandlergt() - container.RegisterltIQuotes, StockQuotesgt()
- container.RegisterltIAuthenticator,
Authenticatorgt() - container.RegisterltIWebApp, WebAppgt()
14Setting Up the Container (XML)
- ltDIContainergt
- ltTypeMap fromILogger toLogger /gt
- ltTypeMap fromIDatabase toDatabase /gt
- ltTypeMap fromIErrorHandler toErrorHandler
/gt - ltTypeMap fromIQuotes toStockQuotes /gt
- ltTypeMap fromIAuthenticator toAuthenticator
/gt - lt/DIContainergt
15Creating Objects
- Test
- public void WebAppTest()
-
- DIContainer container GetContainer()
- IStockQuotes quotes container.GetltIStockQuotes
gt() - IAuthenticator auth container.GetltIAuthenticat
orgt() -
- Assert.IsNotNull( quotes.Logger )
- Assert.IsNotNull( auth.Logger )
- Assert.AreSame( quotes.Logger, auth.Logger )
16The Possibilities are Endless?
- To Singleton or Not to Singleton?
- Nested Containers
- Property Setter
- Object Lifetime
- Method Invocation
- Event Wire-up
- Instrumentation
- Method Interception via Dynamic Proxies
17Existing Frameworks
- Java
- Pico Container
- Spring Framework
- HiveMind
- Ruby
- Rico
- Copland
- Python
- PyContainer
- .NET
- Pico.NET
- Spring.NET
- pp Object Builder
18Demo
- patterns practices Object Builder
19Looking for a Job?
- patterns practices is hiring
- See one of us after the talk or e-mailDarrel
Snow dsnow_at_microsoft.com