Dependency injection

47
Embarrassing coupling problem? Let’s solve that with Cory House @housecor | bitnative.com Dependency Injection

Transcript of Dependency injection

Page 1: Dependency injection

Embarrassing coupling problem?

Let’s solve that with

Cory House@housecor | bitnative.com

Dependency Injection

Page 2: Dependency injection

Here’s the plan

• Why• Composition root• Injection locations• Poor man’s DI• Contrast IoC containers• Configuration styles• Lifestyles• Anti-patterns• Cross-cutting concerns

Page 3: Dependency injection

Tightly coupled

Loosely coupled

Page 4: Dependency injection

Inversion of Control

Dependency InjectionASP.Net Page Lifecycle

Page 5: Dependency injection

Why DI?Object compositionTestability Maintainability Lifetime ManagementPerformance Late bindingExtensibilityParallel developmentCross-cutting concerns (AOP)

Page 6: Dependency injection

SOLID

Page 7: Dependency injection

Code to an abstraction, not an implementation

Page 8: Dependency injection

Interfaces

Page 9: Dependency injection

Tightly coupled

Loosely coupled

Page 10: Dependency injection

Collaborating classes should rely on infrastructure to provide services.

Page 11: Dependency injection

Demo: Poor man’s DI

Page 12: Dependency injection

Is new evil?

var user = new User()

Page 13: Dependency injection

Watch for Volatility

new StringBuilder()new List<T>()System.Xml

App specificnew User, Product, Order

Non-deterministicDateTime.Now, File, Data

SlowRemote service

Page 14: Dependency injection

Composition Root

• Where the app “starts”• Classes are composed here• Keeps app unaware of the IoC container • Unique techniques for different techs

Page 15: Dependency injection

Composition RootTechnology 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

Page 16: Dependency injection

Register, Resolve, Release

Page 17: Dependency injection

Injection Location

1. Constructor2. Property3. Method

Location Usage Benefits Drawbacks

Constructor When possible SimpleGuarantees injectionExplicit

Tricky (some frameworks)Object graph on startup

Property Good local default Easy to understand Not simple to implement

Method Dependency varies by method call

Caller provides operation specific context

Limited applicability

Page 18: Dependency injection

Config Styles1.XML2.Code (aka fluent)3.Auto-registration

Page 19: Dependency injection

Demo: Config Styles

Page 20: Dependency injection

Config StylesMapping Advantages Disadvantages

Config Late binding

Control

No compile-time checks

VerboseCode Compile-time checks

Control

Intellisense

Must recompile

Rules Late binding

Automatic = Less work

Reinforces conventions

Partial compile-time checks

Less control

Magic

XML

Code

Auto-Registration

Page 21: Dependency injection

Config Style SupportStyle Castle Windsor StructureMap Spring.Net Autofac Unity

XML X X X X X

Code X X X X

Auto-registration X X X

Page 22: Dependency injection

XML Code as Configuration

Late Binding Early Binding

Explicit

Implicit

Auto Registration

Page 23: Dependency injection

LifestylesLifestyle Description Usage

Singleton Once on App startup. Most efficient.

Thread safe, stateless, immutable, circuit breaker, in-memory cache

Transient Per Request. Least efficient. Default (most)

Per Graph One instance of each dependency per thread

Anywhere thread that resolves is the only consumer of the graph. Efficient alt to transient.

Web Request Context

One instance per web request Web app requests when singleton won’t work

Thread Context Per thread

Session Context Per session

Pooled Pool of ready objects Expensive to create

Scoped

Custom

Page 24: Dependency injection

Lifestyle SupportLifestyle Castle

WindsorStructureMap Spring.Net Autofac Unity

Singleton X X X X X

Transient X X X X X

Per Graph X X

Web Request Context

X X (X) X

Thread Context

X X X

Session Context

X (X)

Pooled X

Scoped X X

Custom X X X

Page 25: Dependency injection

Warning

Windsor: SingletonStructureMap: Transient

Release transients or burn all RAM

Page 26: Dependency injection

Demo: Coupling

Page 27: Dependency injection

Control Freak

Page 28: Dependency injection

Control Freak: Solutions

• Factory – moves problem to another class

• Static factory that calls config – No easy way to inject mock for unit testing.

• Constructor or property injection

Page 29: Dependency injection

Service Locator: Anti-pattern?

Service Locator: Ask for

dependencyDI: Consumer

supplies dependency

Page 30: Dependency injection

Demo: Service Locator

Page 31: Dependency injection

Problems with Service Locator

• Hides dependencies• IoC container tightly coupled• Drags in other modules if IoC container is in

separate module

Page 32: Dependency injection

Anti-Patterns: Bastard Injection

ForeignDefault

Page 33: Dependency injection

Bastard Injection

1. Overloaded constructor = ambiguity2. Often introduces foreign dependency3. Hinders parallel development

• Fix– Foreign default: Constructor injection– Local default: Property injection

Page 34: Dependency injection

Other Anti-Patterns

• Factory that references config• Constructor over injection• MVC’s Idependency Resolver• Abstracting away your container• Web Forms

Page 35: Dependency injection

Cross-Cutting Concerns

Presentation

Domain

Data

Auditing,Logging,Security,

Etc.

Page 36: Dependency injection

Cross-cutting concerns

Problems:AuditingLoggingSecurityError handlingPerf MonitoringCachingFault tolerance

Solution: Dynamic Proxies Decorator PatternHonor SRP Honor Open/Closed

Page 37: Dependency injection

Cross-cutting concerns

Two approaches:1. Dynamic Proxies2. IL Weaving

Page 38: Dependency injection

PostSharp

Attributes Normal Compilation

PostSharp Compilation

.Net Assembly

Page 39: Dependency injection

AOP via attributes

1. Modify compilation• PostSharp

2. Custom runtime host • WCF• ASP.Net MVC• Unit testing frameworks

Page 40: Dependency injection
Page 41: Dependency injection

AOP via attributes

• No special design effort• Easy to spot since inline• Explicit since in context

• Code runs different from the code you wrote

• Vendor lock-in • Attributes compiled with

code = Tightly coupled.• Can’t vary the aspect

independently of the implementation

• Can’t use conventions

Page 42: Dependency injection

How do I choose a container?

PerformanceLifetimesDocumentationAPISupportDynamic proxies

Page 43: Dependency injection

Summary

1. Compose at composition root2. Prefer constructor injection, auto-registration3. Volatility? Think smoke detectors vs sockets

Page 44: Dependency injection

Next Steps

Page 45: Dependency injection

@housecor | bitnative.com

Thanks for listening!

Page 47: Dependency injection

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.