Embarrassing coupling problem?

        Let’s solve that with
Dependency Injection
           Cory House
     @housecor | bitnative.com
Here’s the plan
•   Why
•   Composition root
•   Injection locations
•   Poor man’s DI
•   Contrast IoC containers
•   Configuration styles
•   Lifestyles
•   Anti-patterns
•   Cross-cutting concerns
Tightly coupled




Loosely coupled
Inversion of Control

Dependency Injection
ASP.Net Page Lifecycle
Why DI?
Object composition
Testability
Maintainability
Lifetime Management
Performance
Late binding
Extensibility
Parallel development
Cross-cutting concerns (AOP)
SOLID
Code to an abstraction, not an implementation
Interfaces
Tightly coupled




Loosely coupled
Collaborating classes should
rely on infrastructure to
provide services.
Demo: Poor man’s DI
Is new evil?

var user = new User()
Watch for Volatility
new StringBuilder()     App specific
new List<T>()              new User, Product, Order
System.Xml              Non-deterministic
                           DateTime.Now, File, Data
                        Slow
                           Remote service
Composition Root
•   Where the app “starts”
•   Classes are composed here
•   Keeps app unaware of the IoC container
•   Unique techniques for different techs
Composition Root
Technology          Composition Root
Console App         Main method
ASP.NET MVC         Call custom IControllerFactory in Global.asax
WCF                 ServiceHostFactory and a few other tricks
ASP.NET Web Forms   Humble object or Service Locator in each aspx.cs
Register, Resolve, Release
Injection Location
1. Constructor
2. Property
3. Method
Location    Usage              Benefits             Drawbacks
Constructor When possible      Simple               Tricky (some frameworks)
                               Guarantees injection Object graph on startup
                               Explicit
Property    Good local default Easy to understand   Not simple to implement
Method      Dependency         Caller provides      Limited applicability
            varies by method   operation specific
            call               context
Config Styles
1.XML
2.Code (aka fluent)
3.Auto-registration
Demo: Config Styles
Config Styles
                    Mapping    Advantages              Disadvantages
           XML      Config     Late binding            No compile-time checks

                               Control                 Verbose
           Code     Code       Compile-time checks     Must recompile

                               Control

                               Intellisense
Auto-Registration   Rules      Late binding            Partial compile-time checks

                               Automatic = Less work   Less control

                               Reinforces conventions Magic
Config Style Support
Style               Castle Windsor   StructureMap Spring.Net Autofac   Unity
XML                       X               X           X         X        X
Code                      X               X                     X        X
Auto-registration         X               X                     X
Explicit


XML                                   Code as
                                      Configuration




  Late Binding                  Early Binding




                 Auto
                 Registration



                   Implicit
Lifestyles
Lifestyle         Description                     Usage
Singleton         Once on App startup. Most       Thread safe, stateless,
                  efficient.                      immutable, circuit breaker, in-
                                                  memory cache
Transient         Per Request. Least efficient.   Default (most)
Per Graph         One instance of each            Anywhere thread that resolves is
                  dependency per thread           the only consumer of the graph.
                                                  Efficient alt to transient.
Web Request       One instance per web request    Web app requests when
Context                                           singleton won’t work
Thread Context    Per thread
Session Context   Per session
Pooled            Pool of ready objects           Expensive to create
Scoped
Custom
Lifestyle Support
Lifestyle   Castle     StructureMap   Spring.Net   Autofac   Unity
            Windsor
Singleton      X             X             X           X             X
Transient      X             X             X           X             X
Per Graph                    X                                       X
Web            X             X            (X)                        X
Request
Context
Thread         X             X                                       X
Context
Session                      X            (X)
Context
Pooled         X
Scoped                                                 X             X
Custom         X             X                                       X
Warning
Windsor: Singleton
StructureMap: Transient

Release transients or burn all RAM
Demo: Coupling
Control Freak
Control Freak: Solutions
• Factory – moves             • Constructor or property
  problem to another            injection
  class
• Static factory that calls
  config – No easy way to
  inject mock for unit
  testing.
Service Locator: Anti-pattern?


 Service Locator:
     Ask for        DI: Consumer
   dependency          supplies
                    dependency
Demo: Service Locator
Problems with Service Locator
• Hides dependencies
• IoC container tightly coupled
• Drags in other modules if IoC container is in
  separate module
Anti-Patterns: Bastard Injection




                            Foreign
                            Default
Bastard Injection
1. Overloaded constructor = ambiguity
2. Often introduces foreign dependency
3. Hinders parallel development

• Fix
  – Foreign default: Constructor injection
  – Local default: Property injection
Other Anti-Patterns
•   Factory that references config
•   Constructor over injection
•   MVC’s Idependency Resolver
•   Abstracting away your container
•   Web Forms
Cross-Cutting Concerns

   Presentation


                  Auditing,
                  Logging,
     Domain       Security,
                    Etc.




      Data
Cross-cutting concerns
Problems:           Solution: Dynamic Proxies
Auditing            Decorator Pattern
Logging             Honor SRP
Security            Honor Open/Closed
Error handling
Perf Monitoring
Caching
Fault tolerance
Cross-cutting concerns
Two approaches:
1. Dynamic Proxies
2. IL Weaving
PostSharp



               Normal       PostSharp      .Net
Attributes
             Compilation   Compilation   Assembly
AOP via attributes
1. Modify compilation
  •   PostSharp

2. Custom runtime host
  •   WCF
  •   ASP.Net MVC
  •   Unit testing frameworks
AOP via attributes
• No special design effort    • Code runs different from
• Easy to spot since inline     the code you wrote
• Explicit since in context   • Vendor lock-in
                              • Attributes compiled with
                                code = Tightly coupled.
                              • Can’t vary the aspect
                                independently of the
                                implementation
                              • Can’t use conventions
How do I choose a container?
Performance
Lifetimes
Documentation
API
Support
Dynamic proxies
Summary
1. Compose at composition root
2. Prefer constructor injection, auto-registration
3. Volatility? Think smoke detectors vs sockets
Next Steps
Thanks for listening!




@housecor | bitnative.com
Example project on Git
Performance Benchmarks
To Do
• Remove references to data layer(s) in MVC
  project. Surprising that ploeh did it in his, but
  clearly a risky issue since it means others
  might tightly couple
• Add checks in project to protect from bad refs.

Dependency injection

  • 1.
    Embarrassing coupling problem? Let’s solve that with Dependency Injection Cory House @housecor | bitnative.com
  • 2.
    Here’s the plan • Why • Composition root • Injection locations • Poor man’s DI • Contrast IoC containers • Configuration styles • Lifestyles • Anti-patterns • Cross-cutting concerns
  • 3.
  • 4.
    Inversion of Control DependencyInjection ASP.Net Page Lifecycle
  • 5.
    Why DI? Object composition Testability Maintainability LifetimeManagement Performance Late binding Extensibility Parallel development Cross-cutting concerns (AOP)
  • 6.
  • 7.
    Code to anabstraction, not an implementation
  • 8.
  • 9.
  • 10.
    Collaborating classes should relyon infrastructure to provide services.
  • 11.
  • 12.
    Is new evil? varuser = new User()
  • 13.
    Watch for Volatility newStringBuilder() App specific new List<T>() new User, Product, Order System.Xml Non-deterministic DateTime.Now, File, Data Slow Remote service
  • 14.
    Composition Root • Where the app “starts” • Classes are composed here • Keeps app unaware of the IoC container • Unique techniques for different techs
  • 15.
    Composition Root Technology Composition Root Console App Main method ASP.NET MVC Call custom IControllerFactory in Global.asax WCF ServiceHostFactory and a few other tricks ASP.NET Web Forms Humble object or Service Locator in each aspx.cs
  • 16.
  • 17.
    Injection Location 1. Constructor 2.Property 3. Method Location Usage Benefits Drawbacks Constructor When possible Simple Tricky (some frameworks) Guarantees injection Object graph on startup Explicit Property Good local default Easy to understand Not simple to implement Method Dependency Caller provides Limited applicability varies by method operation specific call context
  • 18.
    Config Styles 1.XML 2.Code (akafluent) 3.Auto-registration
  • 19.
  • 20.
    Config Styles Mapping Advantages Disadvantages XML Config Late binding No compile-time checks Control Verbose Code Code Compile-time checks Must recompile Control Intellisense Auto-Registration Rules Late binding Partial compile-time checks Automatic = Less work Less control Reinforces conventions Magic
  • 21.
    Config Style Support Style Castle Windsor StructureMap Spring.Net Autofac Unity XML X X X X X Code X X X X Auto-registration X X X
  • 22.
    Explicit XML Code as Configuration Late Binding Early Binding Auto Registration Implicit
  • 23.
    Lifestyles Lifestyle Description Usage Singleton Once on App startup. Most Thread safe, stateless, efficient. immutable, circuit breaker, in- memory cache Transient Per Request. Least efficient. Default (most) Per Graph One instance of each Anywhere thread that resolves is dependency per thread the only consumer of the graph. Efficient alt to transient. Web Request One instance per web request Web app requests when Context singleton won’t work Thread Context Per thread Session Context Per session Pooled Pool of ready objects Expensive to create Scoped Custom
  • 24.
    Lifestyle Support Lifestyle Castle StructureMap Spring.Net Autofac Unity Windsor Singleton X X X X X Transient X X X X X Per Graph X X Web X X (X) X Request Context Thread X X X Context Session X (X) Context Pooled X Scoped X X Custom X X X
  • 25.
  • 26.
  • 27.
  • 28.
    Control Freak: Solutions •Factory – moves • Constructor or property problem to another injection class • Static factory that calls config – No easy way to inject mock for unit testing.
  • 29.
    Service Locator: Anti-pattern? Service Locator: Ask for DI: Consumer dependency supplies dependency
  • 30.
  • 31.
    Problems with ServiceLocator • Hides dependencies • IoC container tightly coupled • Drags in other modules if IoC container is in separate module
  • 32.
  • 33.
    Bastard Injection 1. Overloadedconstructor = ambiguity 2. Often introduces foreign dependency 3. Hinders parallel development • Fix – Foreign default: Constructor injection – Local default: Property injection
  • 34.
    Other Anti-Patterns • Factory that references config • Constructor over injection • MVC’s Idependency Resolver • Abstracting away your container • Web Forms
  • 35.
    Cross-Cutting Concerns Presentation Auditing, Logging, Domain Security, Etc. Data
  • 36.
    Cross-cutting concerns Problems: Solution: Dynamic Proxies Auditing Decorator Pattern Logging Honor SRP Security Honor Open/Closed Error handling Perf Monitoring Caching Fault tolerance
  • 37.
    Cross-cutting concerns Two approaches: 1.Dynamic Proxies 2. IL Weaving
  • 38.
    PostSharp Normal PostSharp .Net Attributes Compilation Compilation Assembly
  • 39.
    AOP via attributes 1.Modify compilation • PostSharp 2. Custom runtime host • WCF • ASP.Net MVC • Unit testing frameworks
  • 41.
    AOP via attributes •No special design effort • Code runs different from • Easy to spot since inline the code you wrote • Explicit since in context • Vendor lock-in • Attributes compiled with code = Tightly coupled. • Can’t vary the aspect independently of the implementation • Can’t use conventions
  • 42.
    How do Ichoose a container? Performance Lifetimes Documentation API Support Dynamic proxies
  • 43.
    Summary 1. Compose atcomposition root 2. Prefer constructor injection, auto-registration 3. Volatility? Think smoke detectors vs sockets
  • 44.
  • 45.
  • 46.
    Example project onGit Performance Benchmarks
  • 47.
    To Do • Removereferences to data layer(s) in MVC project. Surprising that ploeh did it in his, but clearly a risky issue since it means others might tightly couple • Add checks in project to protect from bad refs.

Editor's Notes

  • #5 Ioc: Broad term. Prog style where framework or runtime control the program flow. For example, ASP.Net lifecycleDI – coined by Martin Folweris a set of software design principles and patterns that enable us to develop loosely coupled code. See pg. 42NOTE: Ioc nicely describes exactly what we’re trying to do.
  • #6 See table page 16Late binding – replace services without recompile
  • #7 SRP - an object should have only a single responsibilityOpen/Closed - open for extension, but closed for modificationLiskovSubstution Principle - objects in a program should be replaceable with instances of their subtypesInterface segregation principle - many client-specific interfaces are better than one general-purpose interface.Dependency Inversion principle -  Depend upon Abstractions. Do not depend upon concretions.
  • #8 Abstract class or interface. I’ll use the word interface for simplicity, but either will do.
  • #13 Note, only the enemy when a volatile dependency. .Net BCL dependencies aren’t. new StringBuilder() is fine, unless for some reason it’s not. The amount of coupling in an application is loosely correlated to the number of times you see the new keyword in the codebase.
  • #17 Pg 82 Each app should only have a single reference to each of the above methods. Why, config should be considered a single atomic action. Once resolved, consider the container read only. Be sure to release what you resolve. Naming convention from Castle Windsor.
  • #18 Property: (aka setter – use when a good local default, but want to allow callers to provide alternative assemblies)
  • #19 benefits on pg 68
  • #27 TightlyCoupled project – HomeController.cs
  • #31 HomeController alternative Index method
  • #33 Common when attempting to make class testable without understanding DIBastard Injection 146
  • #35 T