SlideShare a Scribd company logo
1 of 47
Download to read offline
Designing for Change
Inversion of Control via Dependency Injection

Nate Kohari
About Me


Software Architect at CTI in Akron, OH
Creator of Ninject, a .NET dependency
injection framework
Disclaimer

 There are no
 silver bullets
 Use critical
 thinking when
 evaluating any
 new idea
Goals
What is inversion of control (IoC)?
How can it make our software more
flexible?
What is dependency injection (DI)?
How can we use DI to achieve IoC?
Why should we use a DI framework?
Change Happens

Software seems like it should be easy to
change
As a result, people always find reasons to
change it!
Simple changes can be very difficult to
implement, and have widespread effects
Agile Software

 This has given rise to Agile software
 development methodologies
 Project management strategies aren’t
 enough
 You need to build the flexibility into your
 software itself
Divide and Conquer

When a problem is too complex, break it
into smaller, more easily-solvable
problems
Each problem is a concern
Separation of Concerns (SoC)
Divide and Conquer (cont.)

 Think of your application like a jigsaw
 puzzle
 How should we carve it up?
 How can we recombine the pieces?
 Two measures to consider: cohesion and
 coupling
Cohesion

How similar is the code within a given
class?
Highly-cohesive components = more
flexible software
Single Responsibility Principle (SRP)
Cohesion (BAD)


class Samurai {
  public void Attack(string target) {
    Console.WriteLine(“Chopped {0} in half!”,target);
  }
}
Cohesion (better)
class Samurai {
  public Sword Weapon { get; set; }
  public void Attack(string target) {
    Weapon.Hit(target);
  }
}

class Sword {
  public void Hit(string target) {
    Console.WriteLine(“Chopped {0} in half!”,target);
  }
}
Coupling

How much does a given concrete class
require other concrete classes in order to
operate?
Loosely-coupled components = more
flexible software
Interface Segregation Principle (ISP)
Coupling (BAD)
class Samurai {
  public Sword Weapon { get; set; }
  public void Attack(string target) {
    Weapon.Hit(target);
  }
}

class Sword {
  public void Hit(string target) {
    Console.WriteLine(“Chopped {0} in half!”,target);
  }
}
Coupling (better)
class Samurai {
  public IWeapon Weapon { get; set; }
  public void Attack(string target) {
    Weapon.Hit(target);
  }
}

interface IWeapon {
   void Hit(string target);
}
Coupling (better, cont.)
class Sword : IWeapon {
  public void Hit(string target) {
    Console.WriteLine(“Chopped {0} in half!”,target);
  }
}

class Crossbow : IWeapon {
  public void Hit(string target) {
    Console.WriteLine(“Pierced {0}’s armor.”,target);
  }
}
Cohesion = Good
 Coupling = Bad
It’s All About Dependencies

 Each piece of your app has other pieces
 that it needs to operate (e.g. a Samurai
 needs an IWeapon)
 Once you break your app into pieces, you
 have to glue the pieces back together
 These are called dependencies
The Dependency Trap

class Samurai {
  public IWeapon Weapon { get; }
  public Samurai() {
    Weapon = new Sword();
  }
}


What’s wrong with this code?
The Dependency Trap (cont.)

class Samurai {
  public IWeapon Weapon { get; }
  public Samurai() {
    Weapon = new Sword();
  }
}


Samurai is still strongly coupled to Sword!
The Problem of Control

 By creating the Sword within the Samurai
 type, they’re still tightly coupled!
 Objects should not be responsible for
 creating their own dependencies
 This is the idea behind inversion of control
Dependency Injection

One way of achieving inversion of control
Create the dependencies somewhere
outside the object, and inject them into it
Really just the Strategy pattern used en
masse
Dependency Injection
class Samurai {
  public IWeapon Weapon { get; }
  public Samurai(IWeapon weapon) {
    Weapon = weapon;
  }
  public void Attack(string target) {
    Weapon.Hit(target);
  }
}
Dependency Injection (cont.)

class Program {
  public static void Main() {
    Samurai sam = new Samurai(new Sword());
    sam.Attack(“the evildoers”);
  }
}



This is dependency injection by hand.
Problems with DI by Hand

Wiring up objects by hand is cumbersome
What if your dependencies have
dependencies of their own, etc?
DI frameworks to the rescue!
DI Frameworks

Also called inversion of control containers
DI frameworks are like super-factories
Rather than wiring up dependencies
manually, just tell the framework how the
parts fit together
DI Frameworks (cont.)


 Using a DI framework lowers the “cost” of
 resolving dependencies to almost zero
 This means you’re more likely to make the
 appropriate separations
DI Frameworks (cont.)

 Frameworks galore!
 In Java: Guice, Spring, Pico, Nano
 In .NET: Castle Windsor, StructureMap,
 Spring.NET, ObjectBuilder/Unity
 And of course my personal favorite...
DI with Ninject

class Samurai {
  [Inject] public IWeapon Weapon { get; set; }
  public void Attack(string target) {
    Weapon.Hit(target);
  }
}



The [Inject] attribute marks the dependency.
DI with Ninject (cont.)
class Program {
  public static void Main() {
    IKernel kernel = new StandardKernel(...);
    Samurai sam = kernel.Get<Samurai>();
    sam.Attack(“the evildoers”);
  }
}


When the Samurai is returned from the call to
Get(), it will already be “armed” with a Sword.
The Kernel

The kernel is Ninject’s super-factory
Your application should only have one
kernel (except in very complex cases)
All services should be created via the
kernel, either via Get() or an [Inject]
decoration
DI with Ninject (cont.)

class Samurai {
  [Inject] public IWeapon Weapon { get; set; }
  public void Attack(string target) {
    Weapon.Hit(target);
  }
}


But wait, IWeapon is just an interface!
How does Ninject know what to inject?
Bindings
Bindings are hints that you give to Ninject
Creates a map between a service type and
an implementation type
Lets you build future flexibility into your
code, and then adjust without changing
the code itself
Defined via Ninject’s fluent interface
Bindings (example)

When IWeapon is requested, create a Sword:
Bind<IWeapon>().To<Sword>();



When Samurai is requested, create a Samurai:
Bind<Samurai>().ToSelf();
DSL > XML
Other DI frameworks are geared around
defining bindings in XML
XML is verbose, ugly, and not much better
than plain text
Defining bindings via code lets you take
advantage of IDE features (auto-complete,
type-safety)
Modules

In Ninject, bindings are collected into
modules
Modules are just class definitions
In other containers, you end up with a
monolithic XML file
Your app can have any number of modules
Modules (example)
class WarriorModule : StandardModule {
  public override void Load() {
    Bind<IWeapon>().To<Sword>();
    Bind<Samurai>().ToSelf();
  }
}



Modules are just code, so you can build in as
much intelligence as you want.
Behaviors

Ninject can also help re-use instances
Singleton, one-per-thread, one-per-
request (web)
Separates instantiation behavior from
code, making it easier to change
Singleton (typical)
class Shogun {
  private static Shogun _instance = new Shogun();
  public static Instance {
    get { return _instance; }
  }
  private Shogun() { }
  public void RuleWithIronFist() {
    //...
  }
}
Singleton (Ninject)
[Singleton]
class Shogun {
  public Shogun() { }
  public void RuleWithIronFist() {
    //...
  }
}


The first time a Shogun is requested, it will be
activated, then on subsequent requests the
same instance will be returned.
Advanced Features

Contextual binding: returns different
implementations depending on situation
Loose-coupled events via event broker
Method interception (aspect-oriented
programming)
Contextual Binding
Bind<IWeapon>().To<Sword>(
   When.Context.Target.Tag == “melee”
);

Bind<IWeapon>().To<Crossbow>(
   When.Context.Target.Tag == “range”
);



These conditional bindings examine the
activation context of the current object.
Contextual Binding
class Swordsman {
  [Inject, Tag(“melee”)]
  public IWeapon Weapon { get; set; }
}

class Archer {
  [Inject, Tag(“range”)]
  public IWeapon Weapon { get; set; }
}

Contextual binding is useful for matching
identical type hierarchies.
Loose-Coupled Events
class Publisher {
  [Publish(“SomeEvent”)]
  public event EventHandler SomeEvent;
}

class Subscriber {
  [Subscribe(“SomeEvent”)]
  public void OnSomeEvent(object obj, EventArgs e)
  { ... }
}

Objects can subscribe to event channels
without knowing about actual instances.
Method Interception

class ComplexObjectFactory {
  [Cache] public void Create() {
    // Do something difficult to create object
  }
}



Results in a chain of interceptors being called
before the method itself is executed.
Summary

Make your software more flexible by
maximizing cohesion and minimizing
coupling
Carve your app into a jigsaw puzzle
Use a DI framework like Ninject to glue
together the pieces
For More Information

http://ninject.org/
http://kohari.org/
http://twitter.com/nkohari


Questions?

More Related Content

Similar to Designing For Change

2011 py con
2011 py con2011 py con
2011 py conEing Ong
 
You Don't Need Dependency Injection
You Don't Need Dependency InjectionYou Don't Need Dependency Injection
You Don't Need Dependency Injectionintive
 
Delegateless Coordinators - take 2
Delegateless Coordinators - take 2Delegateless Coordinators - take 2
Delegateless Coordinators - take 2Tales Andrade
 
Real World Dependency Injection - oscon13
Real World Dependency Injection - oscon13Real World Dependency Injection - oscon13
Real World Dependency Injection - oscon13Stephan Hochdörfer
 
Android_Bootcamp_PPT_GDSC_ITS_Engineering
Android_Bootcamp_PPT_GDSC_ITS_EngineeringAndroid_Bootcamp_PPT_GDSC_ITS_Engineering
Android_Bootcamp_PPT_GDSC_ITS_EngineeringShivanshSeth6
 
Delegateless Coordinator
Delegateless CoordinatorDelegateless Coordinator
Delegateless CoordinatorTales Andrade
 
Dependency Injection, Zend Framework and Symfony Container
Dependency Injection, Zend Framework and Symfony ContainerDependency Injection, Zend Framework and Symfony Container
Dependency Injection, Zend Framework and Symfony ContainerDiego Lewin
 
Working Effectively With Legacy Code
Working Effectively With Legacy CodeWorking Effectively With Legacy Code
Working Effectively With Legacy CodeNaresh Jain
 
Application Frameworks: The new kids on the block
Application Frameworks: The new kids on the blockApplication Frameworks: The new kids on the block
Application Frameworks: The new kids on the blockRichard Lord
 
2. Design patterns. part #2
2. Design patterns. part #22. Design patterns. part #2
2. Design patterns. part #2Leonid Maslov
 
Real World Dependency Injection - phpday
Real World Dependency Injection - phpdayReal World Dependency Injection - phpday
Real World Dependency Injection - phpdayStephan Hochdörfer
 
SOLID & IoC Principles
SOLID & IoC PrinciplesSOLID & IoC Principles
SOLID & IoC PrinciplesPavlo Hodysh
 
Gnizr Architecture (for developers)
Gnizr Architecture (for developers)Gnizr Architecture (for developers)
Gnizr Architecture (for developers)hchen1
 
Java Performance Tuning
Java Performance TuningJava Performance Tuning
Java Performance TuningMinh Hoang
 
Introduction to Backbone.js & Marionette.js
Introduction to Backbone.js & Marionette.jsIntroduction to Backbone.js & Marionette.js
Introduction to Backbone.js & Marionette.jsReturn on Intelligence
 

Similar to Designing For Change (20)

Robots in Swift
Robots in SwiftRobots in Swift
Robots in Swift
 
2011 py con
2011 py con2011 py con
2011 py con
 
You don't need DI
You don't need DIYou don't need DI
You don't need DI
 
You Don't Need Dependency Injection
You Don't Need Dependency InjectionYou Don't Need Dependency Injection
You Don't Need Dependency Injection
 
Thinking In Swift
Thinking In SwiftThinking In Swift
Thinking In Swift
 
Delegateless Coordinators - take 2
Delegateless Coordinators - take 2Delegateless Coordinators - take 2
Delegateless Coordinators - take 2
 
Real World Dependency Injection - oscon13
Real World Dependency Injection - oscon13Real World Dependency Injection - oscon13
Real World Dependency Injection - oscon13
 
Anti Object-Oriented Design Patterns
Anti Object-Oriented Design PatternsAnti Object-Oriented Design Patterns
Anti Object-Oriented Design Patterns
 
Android_Bootcamp_PPT_GDSC_ITS_Engineering
Android_Bootcamp_PPT_GDSC_ITS_EngineeringAndroid_Bootcamp_PPT_GDSC_ITS_Engineering
Android_Bootcamp_PPT_GDSC_ITS_Engineering
 
Delegateless Coordinator
Delegateless CoordinatorDelegateless Coordinator
Delegateless Coordinator
 
Dependency Injection, Zend Framework and Symfony Container
Dependency Injection, Zend Framework and Symfony ContainerDependency Injection, Zend Framework and Symfony Container
Dependency Injection, Zend Framework and Symfony Container
 
Working Effectively With Legacy Code
Working Effectively With Legacy CodeWorking Effectively With Legacy Code
Working Effectively With Legacy Code
 
Application Frameworks: The new kids on the block
Application Frameworks: The new kids on the blockApplication Frameworks: The new kids on the block
Application Frameworks: The new kids on the block
 
2. Design patterns. part #2
2. Design patterns. part #22. Design patterns. part #2
2. Design patterns. part #2
 
Real World Dependency Injection - phpday
Real World Dependency Injection - phpdayReal World Dependency Injection - phpday
Real World Dependency Injection - phpday
 
SOLID & IoC Principles
SOLID & IoC PrinciplesSOLID & IoC Principles
SOLID & IoC Principles
 
Gnizr Architecture (for developers)
Gnizr Architecture (for developers)Gnizr Architecture (for developers)
Gnizr Architecture (for developers)
 
Automating Analysis with the API
Automating Analysis with the APIAutomating Analysis with the API
Automating Analysis with the API
 
Java Performance Tuning
Java Performance TuningJava Performance Tuning
Java Performance Tuning
 
Introduction to Backbone.js & Marionette.js
Introduction to Backbone.js & Marionette.jsIntroduction to Backbone.js & Marionette.js
Introduction to Backbone.js & Marionette.js
 

Recently uploaded

Unveiling Business Expansion Trends in 2024
Unveiling Business Expansion Trends in 2024Unveiling Business Expansion Trends in 2024
Unveiling Business Expansion Trends in 2024Champak Jhagmag
 
『澳洲文凭』买科廷大学毕业证书成绩单办理澳洲Curtin文凭学位证书
『澳洲文凭』买科廷大学毕业证书成绩单办理澳洲Curtin文凭学位证书『澳洲文凭』买科廷大学毕业证书成绩单办理澳洲Curtin文凭学位证书
『澳洲文凭』买科廷大学毕业证书成绩单办理澳洲Curtin文凭学位证书rnrncn29
 
212MTAMount Durham University Bachelor's Diploma in Technology
212MTAMount Durham University Bachelor's Diploma in Technology212MTAMount Durham University Bachelor's Diploma in Technology
212MTAMount Durham University Bachelor's Diploma in Technologyz xss
 
House of Commons ; CDC schemes overview document
House of Commons ; CDC schemes overview documentHouse of Commons ; CDC schemes overview document
House of Commons ; CDC schemes overview documentHenry Tapper
 
(中央兰开夏大学毕业证学位证成绩单-案例)
(中央兰开夏大学毕业证学位证成绩单-案例)(中央兰开夏大学毕业证学位证成绩单-案例)
(中央兰开夏大学毕业证学位证成绩单-案例)twfkn8xj
 
Stock Market Brief Deck FOR 4/17 video.pdf
Stock Market Brief Deck FOR 4/17 video.pdfStock Market Brief Deck FOR 4/17 video.pdf
Stock Market Brief Deck FOR 4/17 video.pdfMichael Silva
 
magnetic-pensions-a-new-blueprint-for-the-dc-landscape.pdf
magnetic-pensions-a-new-blueprint-for-the-dc-landscape.pdfmagnetic-pensions-a-new-blueprint-for-the-dc-landscape.pdf
magnetic-pensions-a-new-blueprint-for-the-dc-landscape.pdfHenry Tapper
 
Governor Olli Rehn: Dialling back monetary restraint
Governor Olli Rehn: Dialling back monetary restraintGovernor Olli Rehn: Dialling back monetary restraint
Governor Olli Rehn: Dialling back monetary restraintSuomen Pankki
 
SBP-Market-Operations and market managment
SBP-Market-Operations and market managmentSBP-Market-Operations and market managment
SBP-Market-Operations and market managmentfactical
 
Market Morning Updates for 16th April 2024
Market Morning Updates for 16th April 2024Market Morning Updates for 16th April 2024
Market Morning Updates for 16th April 2024Devarsh Vakil
 
原版1:1复刻堪萨斯大学毕业证KU毕业证留信学历认证
原版1:1复刻堪萨斯大学毕业证KU毕业证留信学历认证原版1:1复刻堪萨斯大学毕业证KU毕业证留信学历认证
原版1:1复刻堪萨斯大学毕业证KU毕业证留信学历认证jdkhjh
 
NO1 Certified kala jadu karne wale ka contact number kala jadu karne wale bab...
NO1 Certified kala jadu karne wale ka contact number kala jadu karne wale bab...NO1 Certified kala jadu karne wale ka contact number kala jadu karne wale bab...
NO1 Certified kala jadu karne wale ka contact number kala jadu karne wale bab...Amil baba
 
Vp Girls near me Delhi Call Now or WhatsApp
Vp Girls near me Delhi Call Now or WhatsAppVp Girls near me Delhi Call Now or WhatsApp
Vp Girls near me Delhi Call Now or WhatsAppmiss dipika
 
government_intervention_in_business_ownership[1].pdf
government_intervention_in_business_ownership[1].pdfgovernment_intervention_in_business_ownership[1].pdf
government_intervention_in_business_ownership[1].pdfshaunmashale756
 
原版1:1复刻温哥华岛大学毕业证Vancouver毕业证留信学历认证
原版1:1复刻温哥华岛大学毕业证Vancouver毕业证留信学历认证原版1:1复刻温哥华岛大学毕业证Vancouver毕业证留信学历认证
原版1:1复刻温哥华岛大学毕业证Vancouver毕业证留信学历认证rjrjkk
 
Economics, Commerce and Trade Management: An International Journal (ECTIJ)
Economics, Commerce and Trade Management: An International Journal (ECTIJ)Economics, Commerce and Trade Management: An International Journal (ECTIJ)
Economics, Commerce and Trade Management: An International Journal (ECTIJ)ECTIJ
 
Stock Market Brief Deck for "this does not happen often".pdf
Stock Market Brief Deck for "this does not happen often".pdfStock Market Brief Deck for "this does not happen often".pdf
Stock Market Brief Deck for "this does not happen often".pdfMichael Silva
 
Call Girls Near Golden Tulip Essential Hotel, New Delhi 9873777170
Call Girls Near Golden Tulip Essential Hotel, New Delhi 9873777170Call Girls Near Golden Tulip Essential Hotel, New Delhi 9873777170
Call Girls Near Golden Tulip Essential Hotel, New Delhi 9873777170Sonam Pathan
 
Financial analysis on Risk and Return.ppt
Financial analysis on Risk and Return.pptFinancial analysis on Risk and Return.ppt
Financial analysis on Risk and Return.ppttadegebreyesus
 
Role of Information and technology in banking and finance .pptx
Role of Information and technology in banking and finance .pptxRole of Information and technology in banking and finance .pptx
Role of Information and technology in banking and finance .pptxNarayaniTripathi2
 

Recently uploaded (20)

Unveiling Business Expansion Trends in 2024
Unveiling Business Expansion Trends in 2024Unveiling Business Expansion Trends in 2024
Unveiling Business Expansion Trends in 2024
 
『澳洲文凭』买科廷大学毕业证书成绩单办理澳洲Curtin文凭学位证书
『澳洲文凭』买科廷大学毕业证书成绩单办理澳洲Curtin文凭学位证书『澳洲文凭』买科廷大学毕业证书成绩单办理澳洲Curtin文凭学位证书
『澳洲文凭』买科廷大学毕业证书成绩单办理澳洲Curtin文凭学位证书
 
212MTAMount Durham University Bachelor's Diploma in Technology
212MTAMount Durham University Bachelor's Diploma in Technology212MTAMount Durham University Bachelor's Diploma in Technology
212MTAMount Durham University Bachelor's Diploma in Technology
 
House of Commons ; CDC schemes overview document
House of Commons ; CDC schemes overview documentHouse of Commons ; CDC schemes overview document
House of Commons ; CDC schemes overview document
 
(中央兰开夏大学毕业证学位证成绩单-案例)
(中央兰开夏大学毕业证学位证成绩单-案例)(中央兰开夏大学毕业证学位证成绩单-案例)
(中央兰开夏大学毕业证学位证成绩单-案例)
 
Stock Market Brief Deck FOR 4/17 video.pdf
Stock Market Brief Deck FOR 4/17 video.pdfStock Market Brief Deck FOR 4/17 video.pdf
Stock Market Brief Deck FOR 4/17 video.pdf
 
magnetic-pensions-a-new-blueprint-for-the-dc-landscape.pdf
magnetic-pensions-a-new-blueprint-for-the-dc-landscape.pdfmagnetic-pensions-a-new-blueprint-for-the-dc-landscape.pdf
magnetic-pensions-a-new-blueprint-for-the-dc-landscape.pdf
 
Governor Olli Rehn: Dialling back monetary restraint
Governor Olli Rehn: Dialling back monetary restraintGovernor Olli Rehn: Dialling back monetary restraint
Governor Olli Rehn: Dialling back monetary restraint
 
SBP-Market-Operations and market managment
SBP-Market-Operations and market managmentSBP-Market-Operations and market managment
SBP-Market-Operations and market managment
 
Market Morning Updates for 16th April 2024
Market Morning Updates for 16th April 2024Market Morning Updates for 16th April 2024
Market Morning Updates for 16th April 2024
 
原版1:1复刻堪萨斯大学毕业证KU毕业证留信学历认证
原版1:1复刻堪萨斯大学毕业证KU毕业证留信学历认证原版1:1复刻堪萨斯大学毕业证KU毕业证留信学历认证
原版1:1复刻堪萨斯大学毕业证KU毕业证留信学历认证
 
NO1 Certified kala jadu karne wale ka contact number kala jadu karne wale bab...
NO1 Certified kala jadu karne wale ka contact number kala jadu karne wale bab...NO1 Certified kala jadu karne wale ka contact number kala jadu karne wale bab...
NO1 Certified kala jadu karne wale ka contact number kala jadu karne wale bab...
 
Vp Girls near me Delhi Call Now or WhatsApp
Vp Girls near me Delhi Call Now or WhatsAppVp Girls near me Delhi Call Now or WhatsApp
Vp Girls near me Delhi Call Now or WhatsApp
 
government_intervention_in_business_ownership[1].pdf
government_intervention_in_business_ownership[1].pdfgovernment_intervention_in_business_ownership[1].pdf
government_intervention_in_business_ownership[1].pdf
 
原版1:1复刻温哥华岛大学毕业证Vancouver毕业证留信学历认证
原版1:1复刻温哥华岛大学毕业证Vancouver毕业证留信学历认证原版1:1复刻温哥华岛大学毕业证Vancouver毕业证留信学历认证
原版1:1复刻温哥华岛大学毕业证Vancouver毕业证留信学历认证
 
Economics, Commerce and Trade Management: An International Journal (ECTIJ)
Economics, Commerce and Trade Management: An International Journal (ECTIJ)Economics, Commerce and Trade Management: An International Journal (ECTIJ)
Economics, Commerce and Trade Management: An International Journal (ECTIJ)
 
Stock Market Brief Deck for "this does not happen often".pdf
Stock Market Brief Deck for "this does not happen often".pdfStock Market Brief Deck for "this does not happen often".pdf
Stock Market Brief Deck for "this does not happen often".pdf
 
Call Girls Near Golden Tulip Essential Hotel, New Delhi 9873777170
Call Girls Near Golden Tulip Essential Hotel, New Delhi 9873777170Call Girls Near Golden Tulip Essential Hotel, New Delhi 9873777170
Call Girls Near Golden Tulip Essential Hotel, New Delhi 9873777170
 
Financial analysis on Risk and Return.ppt
Financial analysis on Risk and Return.pptFinancial analysis on Risk and Return.ppt
Financial analysis on Risk and Return.ppt
 
Role of Information and technology in banking and finance .pptx
Role of Information and technology in banking and finance .pptxRole of Information and technology in banking and finance .pptx
Role of Information and technology in banking and finance .pptx
 

Designing For Change

  • 1. Designing for Change Inversion of Control via Dependency Injection Nate Kohari
  • 2. About Me Software Architect at CTI in Akron, OH Creator of Ninject, a .NET dependency injection framework
  • 3. Disclaimer There are no silver bullets Use critical thinking when evaluating any new idea
  • 4. Goals What is inversion of control (IoC)? How can it make our software more flexible? What is dependency injection (DI)? How can we use DI to achieve IoC? Why should we use a DI framework?
  • 5. Change Happens Software seems like it should be easy to change As a result, people always find reasons to change it! Simple changes can be very difficult to implement, and have widespread effects
  • 6. Agile Software This has given rise to Agile software development methodologies Project management strategies aren’t enough You need to build the flexibility into your software itself
  • 7. Divide and Conquer When a problem is too complex, break it into smaller, more easily-solvable problems Each problem is a concern Separation of Concerns (SoC)
  • 8. Divide and Conquer (cont.) Think of your application like a jigsaw puzzle How should we carve it up? How can we recombine the pieces? Two measures to consider: cohesion and coupling
  • 9. Cohesion How similar is the code within a given class? Highly-cohesive components = more flexible software Single Responsibility Principle (SRP)
  • 10. Cohesion (BAD) class Samurai { public void Attack(string target) { Console.WriteLine(“Chopped {0} in half!”,target); } }
  • 11. Cohesion (better) class Samurai { public Sword Weapon { get; set; } public void Attack(string target) { Weapon.Hit(target); } } class Sword { public void Hit(string target) { Console.WriteLine(“Chopped {0} in half!”,target); } }
  • 12. Coupling How much does a given concrete class require other concrete classes in order to operate? Loosely-coupled components = more flexible software Interface Segregation Principle (ISP)
  • 13. Coupling (BAD) class Samurai { public Sword Weapon { get; set; } public void Attack(string target) { Weapon.Hit(target); } } class Sword { public void Hit(string target) { Console.WriteLine(“Chopped {0} in half!”,target); } }
  • 14. Coupling (better) class Samurai { public IWeapon Weapon { get; set; } public void Attack(string target) { Weapon.Hit(target); } } interface IWeapon { void Hit(string target); }
  • 15. Coupling (better, cont.) class Sword : IWeapon { public void Hit(string target) { Console.WriteLine(“Chopped {0} in half!”,target); } } class Crossbow : IWeapon { public void Hit(string target) { Console.WriteLine(“Pierced {0}’s armor.”,target); } }
  • 16. Cohesion = Good Coupling = Bad
  • 17. It’s All About Dependencies Each piece of your app has other pieces that it needs to operate (e.g. a Samurai needs an IWeapon) Once you break your app into pieces, you have to glue the pieces back together These are called dependencies
  • 18. The Dependency Trap class Samurai { public IWeapon Weapon { get; } public Samurai() { Weapon = new Sword(); } } What’s wrong with this code?
  • 19. The Dependency Trap (cont.) class Samurai { public IWeapon Weapon { get; } public Samurai() { Weapon = new Sword(); } } Samurai is still strongly coupled to Sword!
  • 20. The Problem of Control By creating the Sword within the Samurai type, they’re still tightly coupled! Objects should not be responsible for creating their own dependencies This is the idea behind inversion of control
  • 21. Dependency Injection One way of achieving inversion of control Create the dependencies somewhere outside the object, and inject them into it Really just the Strategy pattern used en masse
  • 22. Dependency Injection class Samurai { public IWeapon Weapon { get; } public Samurai(IWeapon weapon) { Weapon = weapon; } public void Attack(string target) { Weapon.Hit(target); } }
  • 23. Dependency Injection (cont.) class Program { public static void Main() { Samurai sam = new Samurai(new Sword()); sam.Attack(“the evildoers”); } } This is dependency injection by hand.
  • 24. Problems with DI by Hand Wiring up objects by hand is cumbersome What if your dependencies have dependencies of their own, etc? DI frameworks to the rescue!
  • 25. DI Frameworks Also called inversion of control containers DI frameworks are like super-factories Rather than wiring up dependencies manually, just tell the framework how the parts fit together
  • 26. DI Frameworks (cont.) Using a DI framework lowers the “cost” of resolving dependencies to almost zero This means you’re more likely to make the appropriate separations
  • 27. DI Frameworks (cont.) Frameworks galore! In Java: Guice, Spring, Pico, Nano In .NET: Castle Windsor, StructureMap, Spring.NET, ObjectBuilder/Unity And of course my personal favorite...
  • 28.
  • 29. DI with Ninject class Samurai { [Inject] public IWeapon Weapon { get; set; } public void Attack(string target) { Weapon.Hit(target); } } The [Inject] attribute marks the dependency.
  • 30. DI with Ninject (cont.) class Program { public static void Main() { IKernel kernel = new StandardKernel(...); Samurai sam = kernel.Get<Samurai>(); sam.Attack(“the evildoers”); } } When the Samurai is returned from the call to Get(), it will already be “armed” with a Sword.
  • 31. The Kernel The kernel is Ninject’s super-factory Your application should only have one kernel (except in very complex cases) All services should be created via the kernel, either via Get() or an [Inject] decoration
  • 32. DI with Ninject (cont.) class Samurai { [Inject] public IWeapon Weapon { get; set; } public void Attack(string target) { Weapon.Hit(target); } } But wait, IWeapon is just an interface! How does Ninject know what to inject?
  • 33. Bindings Bindings are hints that you give to Ninject Creates a map between a service type and an implementation type Lets you build future flexibility into your code, and then adjust without changing the code itself Defined via Ninject’s fluent interface
  • 34. Bindings (example) When IWeapon is requested, create a Sword: Bind<IWeapon>().To<Sword>(); When Samurai is requested, create a Samurai: Bind<Samurai>().ToSelf();
  • 35. DSL > XML Other DI frameworks are geared around defining bindings in XML XML is verbose, ugly, and not much better than plain text Defining bindings via code lets you take advantage of IDE features (auto-complete, type-safety)
  • 36. Modules In Ninject, bindings are collected into modules Modules are just class definitions In other containers, you end up with a monolithic XML file Your app can have any number of modules
  • 37. Modules (example) class WarriorModule : StandardModule { public override void Load() { Bind<IWeapon>().To<Sword>(); Bind<Samurai>().ToSelf(); } } Modules are just code, so you can build in as much intelligence as you want.
  • 38. Behaviors Ninject can also help re-use instances Singleton, one-per-thread, one-per- request (web) Separates instantiation behavior from code, making it easier to change
  • 39. Singleton (typical) class Shogun { private static Shogun _instance = new Shogun(); public static Instance { get { return _instance; } } private Shogun() { } public void RuleWithIronFist() { //... } }
  • 40. Singleton (Ninject) [Singleton] class Shogun { public Shogun() { } public void RuleWithIronFist() { //... } } The first time a Shogun is requested, it will be activated, then on subsequent requests the same instance will be returned.
  • 41. Advanced Features Contextual binding: returns different implementations depending on situation Loose-coupled events via event broker Method interception (aspect-oriented programming)
  • 42. Contextual Binding Bind<IWeapon>().To<Sword>( When.Context.Target.Tag == “melee” ); Bind<IWeapon>().To<Crossbow>( When.Context.Target.Tag == “range” ); These conditional bindings examine the activation context of the current object.
  • 43. Contextual Binding class Swordsman { [Inject, Tag(“melee”)] public IWeapon Weapon { get; set; } } class Archer { [Inject, Tag(“range”)] public IWeapon Weapon { get; set; } } Contextual binding is useful for matching identical type hierarchies.
  • 44. Loose-Coupled Events class Publisher { [Publish(“SomeEvent”)] public event EventHandler SomeEvent; } class Subscriber { [Subscribe(“SomeEvent”)] public void OnSomeEvent(object obj, EventArgs e) { ... } } Objects can subscribe to event channels without knowing about actual instances.
  • 45. Method Interception class ComplexObjectFactory { [Cache] public void Create() { // Do something difficult to create object } } Results in a chain of interceptors being called before the method itself is executed.
  • 46. Summary Make your software more flexible by maximizing cohesion and minimizing coupling Carve your app into a jigsaw puzzle Use a DI framework like Ninject to glue together the pieces