Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
http://slideshare.net/CalebJenkins
“The single greatest thing that you can do to make your
code more testable and healthy is to start taking a
Dependency Inj...
Super Spy
(saves the world)
Dr. Evil
(bad guy)
public class DoubleOSuperSpy
{
public void StopDrEvilWithSpyWatch()
{
// Stop Dr. Evil
}
}
but what if we wanted to
rescue the queen
use our spy car
stop nuclear attack,
?
?
?
public class DoubleOSuperSpy
{
public void StopDrEvilWithSpyWatch()
{
// Stop Dr. Evil
}
public void StopDrEvilWithSpyCar(...
public interface ISecretAgent
{
void RunMission(ISecretMission Mission);
}
public interface ISpyGadget
{
void UseGadget(st...
public class DoubleOSuperSpy : ISecretAgent
{
private ISpyGadget spyWatch;
private IMission stopDrEvil;
public DoubleOSupe...
public class DoubleOSuperSpy : ISecretAgent
{
private ISpyGadget spyWatch;
private IMission stopDrEvil;
public DoubleOSupe...
public class Factory
{
public static ISecretAgent GetSecretAgent()
{
// Check config
return new DoubleOSuperSpy();
}
publi...
Factory Pattern
public class DoubleOSuperSpy : ISecretAgent
{
private ISpyGadget gadget;
private ISecretMission mission;
public DoubleOSup...
public class DoubleOSuperSpy : ISecretAgent
{
private ISpyGadget gadget;
private ISecretMission mission;
public DoubleOSup...
public class DoubleOSuperSpy : ISecretAgent
{
private ISpyGadget gadget;
private ISecretMission mission;
public DoubleOSup...
public class DoubleOSuperSpy : ISecretAgent
{
private ISpyGadget gadget;
private ISecretMission mission;
public DoubleOSup...
public class DoubleOSuperSpy : ISecretAgent
{
private ISpyGadget gadget;
private ISecretMission mission;
private DoubleOSu...
public class MyApplication
{
public void static Main()
{
ISecretAgent agent = Factory.GetSecretAgent();
ISpyGadget gadget ...
public class MyApplication
{
public void static Main()
{
ISpyGadget gadget = new SpyWatch();
ISecretMission mission = new ...
Factory
ISpyGadget
ISecretMission
ISecretAgent
MyApplication
Factory
ISpyGadget
ISecretMission
public class MyApplication
{
public void static Main()
{
ISecretAGent agent = Factory.GetSecretAgent();
ISpyGadget gadget ...
Manual
Dependency Injection
public class MyApplication
{
public void static Main()
{
ISecretAgent agent =
(ISecretAgent) C...
Manual
Dependency Injection
public class MyApplication
{
public void static Main()
{
ISecretAgent agent =
(ISecretAgent) C...
castleproject.org
springframework.net
ninject.org
unity.codeplex.com structuremap.github.io
simpleinjector.org
autofac.org
<factoryconfig type="Improving.ProviderFactory, ProviderFactory">
<factories>
<factory interface=“ISpyGadget" assembly=“Ac...
public class DependencyConfigModule : StandardModule
{
public override void Load()
{
// Factory
Bind<IFactory>().To<factor...
public class DependencyConfigModule : StandardModule
{
public override void Load()
{
// Factory
Bind<IFactory>().To<factor...
LET’S LOOK AT
SOME CODE…
Interceptors and
Listeners
Interceptors and
Listeners
The mission has begun
Dr. Evil has been stopped!
It took :22 seconds!
Interceptors and Listeners
Stop Dr. Evil
Dynamic Proxy
Security must be
licensed to kill
(007)
Logging Bond is
about to begin
mission
Interceptors an...
Longest running “complete stack”
Windsor Container
Dynamic Proxy
Active Record (nHibernate)
ASP.NET Mono Rail
Visual Studi...
springframework.net
“Spring Framework” is THE way to
do JAVA development
Spring .NET is the .NET equivalent
Nice bridge fo...
ninject.org
DI “gateway drug”
Light weight / super fast to configure
DI (Integrates with Castle for IoC / AOP)
.NET
Silver...
unity.codeplex.com
github.com/unitycontainer/unity
From Microsoft
Integration with other Application Blocks
Microsoft Supp...
castleproject.org
springframework.net
ninject.org
unity.codeplex.com structuremap.github.io
simpleinjector.org
autofac.org
commonservicelocator.codeplex.com
IMPLEMENTATION
Castle Windsor Adapter
Spring .NET Adapter
Unity Adapter
StructureMap Ada...
Common Service Locator
commonservicelocator.codeplex.com
Common Service Locator
commonservicelocator.codeplex.com
POOR MAN’S DIpublic class SuperSpyLib
{
private ISecretAgent agent;
private ISpyGadget gadget;
private ISecretMission miss...
POOR MAN’S DIpublic class SuperSpyLib
{
private ISecretAgent agent;
private ISpyGadget gadget;
private ISecretMission miss...
POOR MAN’S DIpublic class SuperSpyLib
{
private ISecretAgent agent;
private ISpyGadget gadget;
private ISecretMission miss...
POOR MAN’S DIpublic class SuperSpyLib
{
private ISecretAgent agent;
private ISpyGadget gadget;
private ISecretMission miss...
POOR MAN’S DIpublic class SuperSpyLib
{
private ISecretAgent agent;
private ISpyGadget gadget;
private ISecretMission miss...
developingUX.com
speakerpedia.com/speakers/caleb-jenkins
@calebjenkins
speakerpedia.com/prog
rammers
developingUX.com
speakerpedia.com/speakers/caleb-jenkins
@calebjenkins
Code to DI For - Dependency Injection for Modern Applications
Code to DI For - Dependency Injection for Modern Applications
Code to DI For - Dependency Injection for Modern Applications
Code to DI For - Dependency Injection for Modern Applications
Code to DI For - Dependency Injection for Modern Applications
Code to DI For - Dependency Injection for Modern Applications
Code to DI For - Dependency Injection for Modern Applications
Code to DI For - Dependency Injection for Modern Applications
Code to DI For - Dependency Injection for Modern Applications
Code to DI For - Dependency Injection for Modern Applications
Code to DI For - Dependency Injection for Modern Applications
Code to DI For - Dependency Injection for Modern Applications
Code to DI For - Dependency Injection for Modern Applications
Code to DI For - Dependency Injection for Modern Applications
Code to DI For - Dependency Injection for Modern Applications
Code to DI For - Dependency Injection for Modern Applications
Code to DI For - Dependency Injection for Modern Applications
Upcoming SlideShare
Loading in …5
×

Code to DI For - Dependency Injection for Modern Applications

1,092 views

Published on

This talk introduces the concepts of factories, strategy pattern, Inversion of Control, dependency injection and several of the available frameworks. We'll also look at common dependency injection patterns and various IoC/DI frameworks, the pros & cons, practical steps and guidance as well some of the real world scenarios with impact to unit testing and application architecture.

First presented at the Ft. Worth .NET Users Group on March 15th, 2016 - http://developingux.com/2016/03/14/code-to-di-for-in-ft-worth/ - Code will be posted to my GitHub soon! https://github.com/calebjenkins/ (Talks.Code-to-DI-For)

Published in: Software

Code to DI For - Dependency Injection for Modern Applications

  1. 1. http://slideshare.net/CalebJenkins
  2. 2. “The single greatest thing that you can do to make your code more testable and healthy is to start taking a Dependency Injection approach to writing software” - Real World .NET, C# and Silverlight Wrox Press 2012 Caleb Jenkins
  3. 3. Super Spy (saves the world) Dr. Evil (bad guy)
  4. 4. public class DoubleOSuperSpy { public void StopDrEvilWithSpyWatch() { // Stop Dr. Evil } }
  5. 5. but what if we wanted to rescue the queen use our spy car stop nuclear attack,
  6. 6. ?
  7. 7. ?
  8. 8. ?
  9. 9. public class DoubleOSuperSpy { public void StopDrEvilWithSpyWatch() { // Stop Dr. Evil } public void StopDrEvilWithSpyCar() { } public void SaveQueenWithSecretCrocodile() { } // Etc... }
  10. 10. public interface ISecretAgent { void RunMission(ISecretMission Mission); } public interface ISpyGadget { void UseGadget(string Target); } public interface ISecretMission { } public class SpyWatch : ISpyGadget public class StopDrEvilMission : ISecretMission public class DoubleOSuperSpy : ISecretAgent
  11. 11. public class DoubleOSuperSpy : ISecretAgent { private ISpyGadget spyWatch; private IMission stopDrEvil; public DoubleOSuperSpy() { spyWatch = new SpyWatch(); stopDrEvil = new StopDrEvilMission(); } public void RunMission() { spyWatch.UseTo(stopDrEvil); } } Separation of Concerns + Grouping of Features = Strategy Pattern
  12. 12. public class DoubleOSuperSpy : ISecretAgent { private ISpyGadget spyWatch; private IMission stopDrEvil; public DoubleOSuperSpy() { spyWatch = new SpyWatch(); stopDrEvil = new StopDrEvilMission(); } public void RunMission() { spyWatch.UseTo(stopDrEvil); } } Interfaces = Looser Coupling
  13. 13. public class Factory { public static ISecretAgent GetSecretAgent() { // Check config return new DoubleOSuperSpy(); } public static ISecretGadget GetSpyGadget() { // Check config return new SpyWatch(); } public static ISecretMission GetSecretMission() { // Check Config return new StopDrEvilMission(); } } A Factory
  14. 14. Factory Pattern
  15. 15. public class DoubleOSuperSpy : ISecretAgent { private ISpyGadget gadget; private ISecretMission mission; public DoubleOSuperSpy() { gadget = Factory.GetSpyGadget(); mission = Factory.GetSecretMission(); } public void UseGadget() { gadget.UserGadget(mission); } } Abstract Factory Pattern = Abstraction of Creation + Polymorphism
  16. 16. public class DoubleOSuperSpy : ISecretAgent { private ISpyGadget gadget; private ISecretMission mission; public DoubleOSuperSpy() { gadget = Factory.GetSpyGadget(); mission = Factory.GetSecretMission(); } public DoubleOSuperSpy (ISecretMission Mission, ISpyGadget Gadget) { mission = Mission; gadget = Gadget; } public ISpyGadget Gadget { set { gadget = Value; } } public void SetMission(ISecretMission Mission) { mission = Mission; } public void UseGadget() { gadget.UseGadget(mission); } public void UseGadget(ISecretMission Mission) Factory Dependency Dependency Injection
  17. 17. public class DoubleOSuperSpy : ISecretAgent { private ISpyGadget gadget; private ISecretMission mission; public DoubleOSuperSpy() { gadget = Factory.GetSpyGadget(); mission = Factory.GetSecretMission(); } public DoubleOSuperSpy (ISecretMission Mission, ISpyGadget Gadget) { mission = Mission; gadget = Gadget; } public ISpyGadet Gadget { set { gadget = Value; } } public void SetMission(ISecretMission Mission) { mission = Mission; } public void UseWeapon(ISecretMission Mission) { gadget.UserGadget(Mission); } public void UseGadget()
  18. 18. public class DoubleOSuperSpy : ISecretAgent { private ISpyGadget gadget; private ISecretMission mission; public DoubleOSuperSpy() { gadget = Factory.GetSpyGadget(); mission = Factory.GetSecretMission(); } public DoubleOSuperSpy (ISecretMission Mission, ISpyGadget Gadget) { mission = Mission; gadget = Gadget; } public ISpyGadget Gadget { set { gadget = Value; } } public void SetMission(ISecretMission Mission) { mission = Mission; } public void RunMission() { gadget.UseGadget(mission); } public void RunMission (ISecretMission Mission) { gadget.UseGadget(Mission); }
  19. 19. public class DoubleOSuperSpy : ISecretAgent { private ISpyGadget gadget; private ISecretMission mission; private DoubleOSuperSpy() { } public DoubleOSuperSpy (ISecretMission Mission, ISpyGadget Gadget) { mission = Mission; gadget = Gadget; } public void RunMission() { gadget.UseGadget(mission); } }
  20. 20. public class MyApplication { public void static Main() { ISecretAgent agent = Factory.GetSecretAgent(); ISpyGadget gadget = Factory.GetSpyGadget(); ISecretMission mission = Factory.GetSecretMission(); // Manual Dependency Injection agent.SetMission(mission); agent.SetGadget(gadget); agent.RunMissionMission(); } } Manual Dependency Injection
  21. 21. public class MyApplication { public void static Main() { ISpyGadget gadget = new SpyWatch(); ISecretMission mission = new StopDrEvilMission(); ISecretAgent agent = new DoubleOSuperSpy(gadget); agent.RunMission(mission); } } Manual Dependency Injection
  22. 22. Factory ISpyGadget ISecretMission ISecretAgent MyApplication Factory ISpyGadget ISecretMission
  23. 23. public class MyApplication { public void static Main() { ISecretAGent agent = Factory.GetSecretAgent(); ISpyGadget gadget = Factory.GetSpyGadget(); ISecretMission mission = Factory.GetSecretMission(); // Manual Dependency Injection agent.SetMission(mission); agent.SetSpyGadget(gadget); agent.RunMission(); } } Manual Dependency Injection
  24. 24. Manual Dependency Injection public class MyApplication { public void static Main() { ISecretAgent agent = (ISecretAgent) Context.GetInstance(“ISecretAgent”); } } Dependency Injection Frameworks
  25. 25. Manual Dependency Injection public class MyApplication { public void static Main() { ISecretAgent agent = (ISecretAgent) Context.GetInstance(“ISecretAgent”); } } Dependency Injection Frameworks public class MyApplication { public void static Main() { ISecretAgent agent = Context.GetInstance<ISecretAgent>(); } } Dependency Injection (with Generics)
  26. 26. castleproject.org springframework.net ninject.org unity.codeplex.com structuremap.github.io simpleinjector.org autofac.org
  27. 27. <factoryconfig type="Improving.ProviderFactory, ProviderFactory"> <factories> <factory interface=“ISpyGadget" assembly=“Acme.MI6" class=“LaserSpyWatch“ /> <factory interface=“ISecretAgent" assembly=“Acme.MI6" class=“DoubleOSuperSpy”> <params> <param name=“Name" value=“Bond, James” type="System.String"/> </params> </factory> <factory interface=“ISecretMission" assembly=“Acme.MI6" class=“StopDrEvilMission“ lifespan=“singleton”> </factory> </factories> </factoryconfig> Dependency Injection Configuration Concepts * Note: This is a conceptual configuration and not specific to any IoC / di framework. Some IoC’s don’t use config, like Ninject that relies on special [attributes] for mappings
  28. 28. public class DependencyConfigModule : StandardModule { public override void Load() { // Factory Bind<IFactory>().To<factory>().Using<SingletonBehavior>(); // Models Bind<ISecretAgent>().To<DoubleOSuperSpy>().Using<TransientBehavior>(); Bind<ISecretMission>().To<StopDrEvilMission>().Using<TransientBehavior>(); Bind<ISpyGadget>().To<LaserSpyWatch>().Using<TransientBehavior>(); } } Dependency Injection Configuration Concepts * Note: This is a conceptual configuration and not specific to any IoC / di framework. Some IoC’s don’t use config, like Ninject that relies on special [attributes] for mappings
  29. 29. public class DependencyConfigModule : StandardModule { public override void Load() { // Factory Bind<IFactory>().To<factory>().Using<SingletonBehavior>(); // Models Bind<ISecretAgent>().To<DoubleOSuperSpy>().Using<TransientBehavior>(); Bind<ISecretMission>().To<StopDrEvilMission>().Using<TransientBehavior>(); Bind<ISpyGadget>().To<LaserSpyWatch>().Using<TransientBehavior>(); } } <factoryconfig type="Improving.ProviderFactory, ProviderFactory"> <factories> <factory interface=“ISpyGadget" assembly=“Acme.MI6" class=“LaserSpyWatch“ /> <factory interface=“ISecretAgent" assembly=“Acme.MI6" class=“DoubleOSuperSpy”> <params> <param name=“Name" value=“Bond, James” type="System.String"/> </params> </factory> <factory interface=“ISecretMission" assembly=“Acme.MI6" class=“StopDrEvilMission“ lifespan=“singleton”> </factory> </factories> </factoryconfig> Dependency Injection Configuration Concepts Implementation Mapping Simple Property Injection Property Injection Constructor Injection Instantiation Model: Singelton Transient Pool * Note: This is a conceptual configuration and not specific to any IoC / di framework. Some IoC’s don’t use config, like Ninject that relies on special [attributes] for mappings Interceptors / Listeners Per Thread Generics
  30. 30. LET’S LOOK AT SOME CODE…
  31. 31. Interceptors and Listeners
  32. 32. Interceptors and Listeners
  33. 33. The mission has begun Dr. Evil has been stopped! It took :22 seconds! Interceptors and Listeners
  34. 34. Stop Dr. Evil Dynamic Proxy Security must be licensed to kill (007) Logging Bond is about to begin mission Interceptors and Listeners (AOP) Multi-Threading Invoke UI Thread
  35. 35. Longest running “complete stack” Windsor Container Dynamic Proxy Active Record (nHibernate) ASP.NET Mono Rail Visual Studio Tooling Well Established Community Integrates with ASP.NET MVC ASP.NET | Sharepoint Winforms | WPF | WCF | WF | Console Apps castleproject.org
  36. 36. springframework.net “Spring Framework” is THE way to do JAVA development Spring .NET is the .NET equivalent Nice bridge for Java Spring developers moving to .NET Interface 21
  37. 37. ninject.org DI “gateway drug” Light weight / super fast to configure DI (Integrates with Castle for IoC / AOP) .NET Silverlight Windows Mobile/Phone No XML Config (Fluent Config)
  38. 38. unity.codeplex.com github.com/unitycontainer/unity From Microsoft Integration with other Application Blocks Microsoft Support Now Maintained by the community (OSS)
  39. 39. castleproject.org springframework.net ninject.org unity.codeplex.com structuremap.github.io simpleinjector.org autofac.org
  40. 40. commonservicelocator.codeplex.com IMPLEMENTATION Castle Windsor Adapter Spring .NET Adapter Unity Adapter StructureMap Adapter Autofac Adapter MEF Adapter now on .NET Framework 4.0 LinFu Adapter Multi-target CSL binaries Service Locator Adapter Implementations
  41. 41. Common Service Locator commonservicelocator.codeplex.com
  42. 42. Common Service Locator commonservicelocator.codeplex.com
  43. 43. POOR MAN’S DIpublic class SuperSpyLib { private ISecretAgent agent; private ISpyGadget gadget; private ISecretMission mission; public void SuperSpyLib (ISecretAgent Agent, ISpyGadget Gadget, ISecretMission Mission) { agent = Agent; gadget = Gadget; mission = Mission; } }
  44. 44. POOR MAN’S DIpublic class SuperSpyLib { private ISecretAgent agent; private ISpyGadget gadget; private ISecretMission mission; public void SuperSpyLib (ISecretAgent Agent, ISpyGadget Gadget, ISecretMission Mission) { agent = Agent; gadget = Gadget; mission = Mission; } }
  45. 45. POOR MAN’S DIpublic class SuperSpyLib { private ISecretAgent agent; private ISpyGadget gadget; private ISecretMission mission; public void SuperSpyLib (ISecretAgent Agent, ISpyGadget Gadget, ISecretMission Mission) { agent = Agent; gadget = Gadget; mission = Mission; } } public class SuperSpyLib { private ISecretAgent agent; private ISpyGadget gadget; private ISecretMission mission; public void SuperSpyLib (ISecretAgent Agent, ISpyGadget Gadget, ISecretMission Mission) { agent = Agent; gadget = Gadget; mission = Mission; } } public void SuperSpyLib () : this (new SuperAgent(), new SpyAgent(), new StopDrEvilMission()) { // Default Constructor – Poor Man’s DI }
  46. 46. POOR MAN’S DIpublic class SuperSpyLib { private ISecretAgent agent; private ISpyGadget gadget; private ISecretMission mission; public void SuperSpyLib (ISecretAgent Agent, ISpyGadget Gadget, ISecretMission Mission) { agent = Agent; gadget = Gadget; mission = Mission; } } public class SuperSpyLib { private ISecretAgent agent; private ISpyGadget gadget; private ISecretMission mission; public void SuperSpyLib (ISecretAgent Agent, ISpyGadget Gadget, ISecretMission Mission) { agent = Agent; gadget = Gadget; mission = Mission; } } public void SuperSpyLib () : this (new SuperAgent(), new SpyAgent(), new StopDrEvilMission()) { // Default Constructor – Poor Man’s DI }
  47. 47. POOR MAN’S DIpublic class SuperSpyLib { private ISecretAgent agent; private ISpyGadget gadget; private ISecretMission mission; public void SuperSpyLib (ISecretAgent Agent, ISpyGadget Gadget, ISecretMission Mission) { agent = Agent; gadget = Gadget; mission = Mission; } } public class SuperSpyLib { private ISecretAgent agent; private ISpyGadget gadget; private ISecretMission mission; public void SuperSpyLib (ISecretAgent Agent, ISpyGadget Gadget, ISecretMission Mission) { agent = Agent; gadget = Gadget; mission = Mission; } } public void SuperSpyLib () : this (new SuperAgent(), new SpyAgent(), new StopDrEvilMission()) { // Default Constructor – Poor Man’s DI }
  48. 48. developingUX.com speakerpedia.com/speakers/caleb-jenkins @calebjenkins
  49. 49. speakerpedia.com/prog rammers
  50. 50. developingUX.com speakerpedia.com/speakers/caleb-jenkins @calebjenkins

×