Evergreen Valley College, Oct. 3rd, 2015
Clean Code II
Dependency Injection
Theo Jungeblut
• Director Customer Success at
AppDynamics in San Francisco
• Coder & software craftsman by night,
first time dad and house builder
• Architects decoupled solutions
& crafts maintainable code to last
• Worked in healthcare and factory
automation, building mission critical
applications, framework & platforms
• Degree in Software Engineering
and Network Communications
• Enjoys cycling, running and eating
theo@designitright.net
www.designitright.net
We are hiring!
http://www.appdynamics.com/ careers
Your feedback is important!
http://speakerrate.com/speakers/18667-theo-jungeblut
Where to get the Slides
http://www.slideshare.net/theojungeblut
Overview
• What is the issue?
• What is Dependency Injection?
• What are Dependencies?
• What is the IoC-Container doing for you?
• What, how, why?
• Q & A
UI
Layer
Service
Layer
Business
Layer
Data
Layer
Web UI
Service
ProcessorProcessor
Service
RepositoryRepository
Mobile UI
Processor
A cleanly layered Architecture
What is the problem?
What is Clean Code?
Clean Code is maintainable
Source code must be:
• readable & well structured
• extensible
• testable
Code Maintainability *
Principles Patterns Containers
Why? How? What?
Extensibility Clean Code Tool reuse
* from: Mark Seemann’s “Dependency Injection in .NET” presentation Bay.NET 05/2011
What is
Dependency Injection?
Without Dependency Injection
public class ExampleClass
{
private Logger logger;
public ExampleClass()
{
this.logger = new Logger();
this.logger.Log(“Constructor call”);
}
}
public class ExampleClass
{
private Logger logger;
public ExampleClass()
{
this.logger = new Logger();
this.logger.Log(“Constructor call”);
}
}
Without Dependency Injection
Inversion of Control –
Constructor Injection
http://www.martinfowler.com/articles/injection.html
public class ExampleClass
{
private ILogger logger;
public ExampleClass(ILogger logger)
{
this.logger = logger;
if (logger == null)
{
throw new ArgumentNullException(“logger”);
}
this.logger.Log(“Constructor call”);
}
}
Why is
Dependency Injection
beneficial?
Benefits of Dependency Injection
Benefit Description
Late binding Services can be swapped with
other services.
Extensibility Code can be extended and reused
in ways not explicitly planned for.
Parallel
development
Code can be developed in parallel.
Maintainability Classes with clearly defined
responsibilities are easier to
maintain.
TESTABILITY Classes can be unit tested.
* from Mark Seemann’s “Dependency Injection in .NET”, page 16
What
are
Dependencies ?
Stable Dependency
“A DEPENDENCY that can be referenced without
any detrimental effects.
The opposite of a VOLATILE DEPENDENCY. “
* From Glossary: Mark Seemann’s “Dependency Injection in .NET”
Volatile Dependency
“A DEPENDENCY that involves side effects that may be
undesirable at times.
This may include modules that don’t yet exist, or that
have adverse requirements on its runtime
environment.
These are the DEPENDENCIES that are addressed by
DI.“
* From Glossary: Mark Seemann’s “Dependency Injection in .NET”
Lifetime
a Job
for the Container
public class ExampleClass
{
private Logger logger;
public ExampleClass()
{
this.logger = new Logger();
this.logger.Log(“Constructor call”);
}
}
Without Dependency Injection
“Register, Resolve, Release”
“Three Calls Pattern by Krzysztof Koźmic: http://kozmic.pl/
1. Register
2. Resolve
Build
up
Your code
Execut
e
Release
Clean
up
What the IoC-Container will do for you
1. Register
2. Resolve
Build
up
Release
Clean
up
Separation of Concern (SoC)
probably by Edsger W. Dijkstra in 1974
You codeExecute
• Focus on purpose of your code
• Know only the contracts of the
dependencies
• No need to know implementations
• No need to handle lifetime of the
dependencies
The 3 Dimensions of DI
1.Object Composition
2.Object Lifetime
3.Interception
Register - Composition Root
• XML based Configuration
• Code based Configuration
• Convention based (Discovery)
Resolve
Resolve a single object request for
example by Constructor Injection by
resolving the needed object graph for
this object.
Release
Release objects from Container
when not needed anymore.
Anti Patterns
Control Freak
http://www.freakingnews.com/The-Puppet-Master-will-play-Pics-102728.asp
// UNITY Example
internal static class Program
{
private static UnityContainer unityContainer;
private static SingleContactManagerForm singleContactManagerForm;
private static void InitializeMainForm()
{
singleContactManagerForm =
unityContainer.Resolve<SingleContactManagerForm>();
}
}
Inversion of Control –
Service Locator
http://www.martinfowler.com/articles/injection.html
// UNITY Example
internal static class Program
{
private static UnityContainer unityContainer;
private static SingleContactManagerForm singleContactManagerForm;
private static void InitializeMainForm()
{
singleContactManagerForm =
unityContainer.Resolve<SingleContactManagerForm>();
}
}
Inversion of Control –
Service Locator
http://www.martinfowler.com/articles/injection.html
Inversion of Control –
Setter (Property) Injection
// UNITY Example
public class ContactManager : IContactManager
{
[Dependency]
public IContactPersistence ContactPersistence
{
get { return this.contactPersistence; }
set { this.contactPersistence = value; }
}
}
http://www.martinfowler.com/articles/injection.html
Property Injection
+ Easy to understand
- Hard to implement robust
* Take if an good default exists
- Limited in application otherwise
Method Injection
public class ContactManager : IContactManager
{
….
public bool Save (IContactPersistencecontactDatabaseService,
IContact contact)
{
if (logger == null)
{
throw new ArgumentNullException(“logger”);
}
…. // Additional business logic executed before calling the save
return contactDatabaseService.Save(contact);
}
}
http://www.martinfowler.com/articles/injection.html
Method Injection
• Needed for handling changing dependencies
in method calls
Ambient Context
public class ContactManager : IContactManager
{
….
public bool Save (….)
{
….
IUser currentUser = ApplicationContext.CurrentUser;
….
}
}
* The Ambient Context object needs to have a default value if not assigned yet.
Ambient Context
• Avoids polluting an API with Cross Cutting
Concerns
• Only for Cross Cutting Concerns
• Limited in application otherwise
The Adapter Pattern
from Gang of Four, “Design Patterns”
Interception
Public class LoggingInterceptor : IContactManager
{
public bool Save(IContact contact)
{
bool success;
this. logger.Log(“Starting saving’);
success =
this.contactManager.Save(contact);
this. logger.Log(“Starting saving’);
return success;
}
}
Public class ContactManager :
IContactManager
{
public bool Save(IContact contact)
{
….
return Result
}
}
* Note: strong simplification of what logically happens through interception.
Dependency Injection Container & more
• Typically support all types of Inversion of Control mechanisms
• Constructor Injection
• Property (Setter) Injection
• Method (Interface) Injection
• Service Locator
•.NET based DI-Container
• Unity
• Castle Windsor
• StructureMap
• Spring.NET
• Autofac
• Puzzle.Nfactory
• Ninject
• PicoContainer.NET
• and more
Related Technology:
• Managed Extensibility Framework (MEF)
The “Must Read”-Book(s)
http://www.manning.com/seemann/
by Mark Seemann
Dependency Injection
is a set of software
design principles and
patterns that enable
us to develop loosely
coupled code.
Summary Clean Code - DI
Maintainability is achieved through:
• Simplification, Specialization Decoupling
(KISS, SoC, IoC, DI)
• Dependency Injection
Constructor Injection as default,
Property and Method Injection as needed,
Ambient Context for Dependencies with a default,
Service Locator never
• Registration
Configuration by Convention if possible, exception in Code as needed
Configuration by XML for explicit extensibility and post compile setup
• Quality through Testability (all of them!)
Graphic by Nathan Sawaya
courtesy of brickartist.com
Downloads,
Feedback & Comments:
Q & A
Graphic by Nathan Sawaya courtesy of brickartist.com
theo@designitright.net
www.designitright.net
http://speakerrate.com/ speakers
/18667-theo-jungeblut
Time to say Thank You!
The Organizers
Evergreen Valley College (team)
The volunteers (how about you?)
TheSponsors
Picturesfromhttp://blog.siliconvalley-codecamp.com
References…
http://www.manning.com/seemann/
http://en.wikipedia.org/wiki/Keep_it_simple_stupid
http://picocontainer.org/patterns.html
http://en.wikipedia.org/wiki/Dependency_inversion_principle
http://en.wikipedia.org/wiki/Don't_repeat_yourself
http://en.wikipedia.org/wiki/Component-oriented_programming
http://en.wikipedia.org/wiki/Service-oriented_architecture
http://www.martinfowler.com/articles/injection.html
http://www.codeproject.com/KB/aspnet/IOCDI.aspx
http://msdn.microsoft.com/en-us/magazine/cc163739.aspx
http://msdn.microsoft.com/en-us/library/ff650320.aspx
http://msdn.microsoft.com/en-us/library/aa973811.aspx
http://msdn.microsoft.com/en-us/library/ff647976.aspx
http://msdn.microsoft.com/en-us/library/cc707845.aspx
http://msdn.microsoft.com/en-us/library/bb833022.aspx
http://unity.codeplex.com/
https://code.google.com/p/autofac/
http://funq.codeplex.com
http://simpleinjector.codeplex.com
http://docs.castleproject.org/Windsor.MainPage.ashx
http://commonservicelocator.codeplex.com
http://philipm.at/2011/di_speed.html
http://www.palmmedia.de/Blog/2011/8/30/ioc-container-benchmark-performance-comparison
http://stackoverflow.com/questions/4581791/how-do-the-major-c-sharp-di-ioc-frameworks-compare
http://diframeworks.apphb.com
http://www.sturmnet.org/blog/2010/03/04/poll-results-ioc-containers-for-net
Lego(trademarkedincapitalsasLEGO)
Blog, Rating, Slides
http://www.DesignItRight.net
http://speakerrate.com/speake
rs/18667-theo-jungeblut
www.slideshare.net/theojungeblut
… thanks for you attention!
And visit and support the
www.siliconvalley-codecamp.com
Please fill out the
feedback, and…
www.speakerrate.com/theoj

Clean Code II - Dependency Injection