Upload
lauren-thornton
View
218
Download
0
Embed Size (px)
Citation preview
Building SOLID Software with Dependency Injection
Jeremy Rosenberg
Me
Who cares about software design?
What are our goals?
• Deliver yesterday• Communicate telepathically• No bugs
What are our goals?
• Deliver yesterday• Communicate telepathically• No bugs
What are our goals?
• Deliver quickly• Communicate quickly• Few bugs• Fix bugs quickly
• Deliver yesterday• Communicate telepathically• No bugs
What are our goals?
• Deliver quickly• Communicate quickly• Few bugs• Fix bugs quickly
• Deliver yesterday• Communicate telepathically• No bugs
aka
Efficiently deal with Change
What is a bad design?
A bad design causes these
• Deliver slowly or unpredictably• Slow ramp-up for new team members• Slow sharing between veteran team members
A bad design causes these
• Frequent bugs• Simple bugs need complex changes• Lots of regressions• Lots of regression testing
What is a good design?
What is SOLID?
What it is
• Catchy acronym• Principles for dealing with change
What it is
• Catchy acronym• Principles for dealing with change
What it is
• Catchy acronym• Principles for dealing with change
SDOLI
What it’s not
• Framework• Library• Pattern• Goal
What is Dependency Injection?
• Pattern• Jives well with SOLID
What kinds of code?
• Object-oriented• Statically typed*
(code examples are in C#)
What does this method do?
What does this method do?– Coordinates a book checkout process for a member
• Checkout• Storage
What does this method do?– Coordinates a book checkout process for a member
• Checkout• Storage
Is that all?
What does this class do?
What does this class do?
• Configuration
• DB Access
So what does this method really do?
• Checkout• Storage
So what does this method really do?
• Checkout• Storage
– Configuration– DB access
Implicit!
Let’s write a test case
SDOLI: Single Responsibility Principle
• “Do one thing and do it well”
• Applies to a method, class, service, system, …
How do we isolate the coordination?
SDOLI: Dependency Inversion Principle
• Depend on contracts, not implementations
• Goal: Decouple the single responsibility from implementations of its dependencies
SDOLI: Dependency Inversion Principle
• Depend on a contract at design-time– e.g. IBookRepository or BookRepositoryBase
• Receive an implementation at runtime– e.g. SqlBookRepository
Dependency Injection
• A class declares its dependencies through its own contract
• Providing dependencies is someone else’s job
Dependency Injection
• Constructor injection• Property injection• Method injection
Constructor injection
Our test case
• No configuration• No database• Only coordination
All this “just” for test cases?
• What else have we gained?– “Tightly bound, loosely coupled”• Focused responsibility => readability• Dependent on behavior, not implementation
– Dependencies are explicit• Limits unexpected side effects• Straightforward (re)usage
– Composability
You’re a hack!
Composition Root
• Constructs the object graph
• Lives near the entry point
Example: Console app
What about that repository?
Make the dependencies explicit
Updated Composition Root
With me?
SDOLI: Open/Closed Principle
• Open for extensibility, closed for modification
• Add behavior without changing existing code
Decorator
• Inject behavior into an application
• Man-in-the-middle
Example: Document storage
Composition Root
Add Logging
Add Logging
Add Authorization
Add Authorization
Add Caching
Add Caching
Noticing a pattern?
Open…
Closed.
Closed.
Closed.
Closed.
Closed.
Composite
• Implements a contract• Delegates to others with the same contract
Example
Build it like this
Use it like this
A more concrete example
Move the responsibility
Notify billing
Notify inventory
Notify shipping
Dispatch all notifications
Open / closed
SDOLI: Liskov Substitution Principle
• Functions that use pointers to base types must be able to use objects of derived types without knowing it.
• “Leaky abstraction principle”-Me
Is a Square a Rectangle?
Is a Square a Rectangle?
SetWidth / SetHeight ?
Example: calculator
Usage
Guess what’s next
Guess what’s next
Guess what’s next
Oops
Plug the leak – Part 1
Plug the leak – Part 1
- Nine fingers left!
Plug the leak – Part 2
What to do
• Some ideas– Kill the abstraction– Adapt each calculator to something that supports
input validation
Another example: more documents…
Read-only integration
Oops
Plug the leak
What to do?
• Some ideas– IReadOnlyDocRepo and IReadWriteDocRepo– IReadDocs and IWriteDocs– SupportsXYZ methods
How can DI help apply the LSP?
How can DI help apply the LSP?
It can’t.
SDOLI: Interface Segregation Principle
• Thin interfaces are better than fat ones
• Client-focused
Example: more books…
Who’s using it?
Cache books?
Don’t need these
These are ok
What about these?
Client-specific interface
Adapter
This:
or this:
Slimmer caching
Focused dependencies
Let’s review
SOLID Principles
• Single Responsibility• Open/Closed• Liskov Substitution• Interface Segregation• Dependency Inversion
I don’t know about you…
DI Container
• Auto-wiring of dependencies
• Lifetime management
Ninject
Ninject
Register
Ninject
Register
Resolve
Ninject
Register
Resolve
Release
Other containers
• Castle Windsor• Autofac• StructureMap• Unity• …
What not to do
Don’t use Service Locator
Don’t use Service Locator
• Hides dependencies• Consumers must use the same container• Testing becomes un-fun
Don’t use Service Locator
• Composition root should be the only place referencing the DI Container.
• General rule: if it’s not just initializing the object graph, it’s not the composition root.
Don’t just new it
Don’t just new it
• Useless interface definition• Same tight coupling• No way to swap, decorate, or otherwise
compose implementations
Don’t be double minded
Don’t be double minded
• Two paths…• Dependencies are still not always apparent• Auto-wiring can be difficult
Building SOLID software
Building SOLID software
• SOLID encourages good designs
• Dependency injection is a tool to bring closer alignment with SOLID
Join us
Resources
• The Principles of OOD http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod
• Dependency Injection in .NET by Mark Seemann
• ploeh blog – DependencyInjection http://blog.ploeh.dk/CategoryView,category,DependencyInjection.aspx
• SOLID (object-oriented design) http://en.wikipedia.org/wiki/SOLID_(object-oriented_design)