Transcript
Page 1: I gotta dependency on dependency injection

I Gotta Dependence on

Dependency Injection

November 15 2014

Matt Henroid (@mhenroid)

Senior Consultant

Daugherty Business Solutions

Page 2: I gotta dependency on dependency injection

Agenda

• SOLID Principles

• Coupling

• Refactoring Dependencies to Abstractions

• Inversion of Control

• Dependency Injection (DI)

– Constructor Injection

– Property / setter injection

– Method injection

– Ambient Context

• Automated Testing

• Object Composition / Lifetime Management

• DI Frameworks

2

Page 3: I gotta dependency on dependency injection

SOLID

• S – Single responsibility

– A class should have only a single responsibility

• O – Open / closed principle

– Classes should be open for extension, but closed for modification

• L – Liskov substitution principle

– Objects of a program should be replaceable with instances of their subtypes

• I – Interface segregation principle

– Many client-specific interfaces are better than one general-purpose interface

• D – Dependency inversion principle

– One should depend on abstractions and not concretions

– Not the same as Dependency Injection but related

3

The 5 commandments of OO design

Page 4: I gotta dependency on dependency injection

ObjectA

InterfaceB InterfaceC

Method1() Method2()

ObjectB ObjectC

Method1() Method2()

Loose Coupling

ObjectA

ObjectB ObjectC

Method1() Method2()

Tight Coupling

Tight vs. Loose Coupling

4

• Coupling

– Degree to which one component (i.e. dependency) has knowledge of another

• Tight Coupling

– A class has a direct reference to a concrete class.

• Loose Coupling

– A class has a reference to an abstraction which can be implemented by one or more

classes.

Page 5: I gotta dependency on dependency injection

ObjectA

InterfaceB InterfaceC

Method1() Method2()

ObjectD ObjectE

Method1() Method2()

Loose Coupling

ObjectA

ObjectD ObjectE

Method1() Method2()

Tight Coupling

Tight vs. Loose Coupling

5

• Benefits of Loose Coupling

– Testability – easier to test objects in isolation

– Reuse – dependencies can be swapped without modifying target

– Open / Closed Principle - change behavior without modifying target

– Parallel development – developers can work in parallel more easily

Page 6: I gotta dependency on dependency injection

Tight Coupling Example

6

Violating Single Responsibility

Page 7: I gotta dependency on dependency injection

Tight Coupling Example

7

How do we test WidgetDataProvider in isolation

from its dependencies?

How can we reuse or change WidgetDataProvider?

Page 8: I gotta dependency on dependency injection

Refactoring Dependencies to Abstractions

• Interfaces

– Every declared method must be implemented by concrete class

• Abstract classes

– Only methods declared abstract must be implemented by concrete class

– Can provide some default implementation for methods not declared abstract

8

Page 9: I gotta dependency on dependency injection

Refactoring Dependencies to Abstractions

• Extract interfaces from classes

9

Before After

Page 10: I gotta dependency on dependency injection

Refactoring Dependencies to Abstractions

• Extract interfaces from classes

• Replace static classes / methods with non-static

10

Before After

Page 11: I gotta dependency on dependency injection

Refactoring Dependencies to Abstractions

• Extract interfaces from classes

• Replace static classes / methods with non-static

• Extract non-deterministic dependencies

– Timers, Threading, DateTime dependent

11

Before After

Page 12: I gotta dependency on dependency injection

Refactoring Dependencies to Abstractions

• Extract interfaces from classes

• Replace static classes / methods with non-static

• Extract non-deterministic dependencies

– Timers, Threading, DateTime dependent

• Replace concretions with abstractions

12

Before After

Page 13: I gotta dependency on dependency injection

Abstraction Example

13

Page 14: I gotta dependency on dependency injection

Inversion of Control (IoC)

• Traditional programming

– Dependencies are instantiated by a class that need them

• Inversion of Control (IoC)

– Dependencies are instantiated by a 3rd party and supplied to a class as needed

14

DependencyA DependencyB

ChildClass

IDependencyA IDependencyB

ChildClass

creates/consumes creates/consumes

ParentClass

creates/consumes

ParentClass

createsconsumes

Traditional Inversion of Control

consumesconsumes

RootContext

consumes

SomeClass creates

SomeClass

creates

SomeClass

creates

SomeClass creates

RootContext

creates/consumes

Page 15: I gotta dependency on dependency injection

Inversion of Control (IoC)

• Dependency Injection

– Constructor Injection

– Property / Setter Injection

– Method Injection

– Ambient Context

• Factory pattern

– Dependencies created by factory class

– Factories can be injected via DI

• Service locator

– Class uses Service Locator to pull dependencies as needed

– Anti-pattern

• Hides a class’ dependencies

• Dependencies magically appear

• Great way to introduce runtime exceptions

– Caution

• Avoid using DI frameworks as Service Locator

15

Implementations

Page 16: I gotta dependency on dependency injection

Dependency Injection

16

Constructor Injection

Use readonly fields as backing store

Inject dependencies via constructor

Guard against null arguments

Save dependencies to field

• When to use

– When a dependency is required

• Important considerations

– Use single constructor

– Keep constructors lightweight

– Minimize number of dependencies (1-3)

Page 17: I gotta dependency on dependency injection

Dependency Injection

17

Property / Setter Injection

Use public get/set to inject dependencies.

Guard against null references (if necessary)

• When to use

– When a dependency is optional or changeable at runtime

– When default constructor is required (ASP.NET Pages/Controls)

Page 18: I gotta dependency on dependency injection

Dependency Injection

18

Method Injection

Dependencies passed as parameters on every call

Guard against null arguments

• When to use

– When a method requires different dependency for each call

Page 19: I gotta dependency on dependency injection

Dependency Injection

19

Ambient Context

Set a default. If no default then use NullObject pattern

Static get/set allows access to current logger

Guard against null values

Implement concrete logger

Extract static methods to an interface

• When to use

– Cross cutting concerns (i.e. Logging, Security, etc.)

– Avoid polluting constructors with global dependencies

• Important considerations

– Thread safety

– Use sparingly

Page 20: I gotta dependency on dependency injection

Automated Testing

• Unit Testing

– Test a class in isolation from dependencies

– Use mock objects in place of dependencies

• Roll your own

• Framework (i.e. Moq)

– Unit tests should never interact with a database

– Should be extremely fast

• Integration Testing

– Test a class along with its dependencies

– More complex than unit tests

– May include database calls which can be slow and brittle

20

Page 21: I gotta dependency on dependency injection

TestInitialize

21

Create fields for our mocks and target for testing

Create mocks and inject as needed

Create mocks and inject into target constructor

Page 22: I gotta dependency on dependency injection

TestMethod

22

GetWidgets() successful path

Configure our mocks to return test data.

Use Verifiable() to ensure that these specific methods

were called.

Execute the method we’re testing

Verify the results are as expected

Page 23: I gotta dependency on dependency injection

TestMethod

23

GetWidgets() exception handling

Configure data feed to throw an exception

Ensure exception is logged

Verify the exception is thrown

Page 24: I gotta dependency on dependency injection

Object Composition / Lifetime Management

• Object Composition

– How and where do we instantiate and inject dependencies?

• Object Lifetime Management

– How do we manage the lifetime of dependencies?

– How do we manage sharing dependencies?

24

Object creation

Use the data provider

Objects go out of scope and are garbage collected.

Page 25: I gotta dependency on dependency injection

Object Composition

• Single place in application where object graph is created

• Nearest the application entry point

• Examples

– Console App = Main method

– Windows Services = Main method

– ASP.NET Web Forms = global.asax

– ASP.NET MVC = IControllerFactory

– WCF = ServiceHostFactory

25

Composition Root

WidgetDataProvider

SqlWidgetDataFeed WidgetDataReader

Simple Object Graph

Composition Root

WidgetDataProvider

SqlWidgetDataFeed WidgetDataReader

More Realistic Object Graph

Composition Root

Page 26: I gotta dependency on dependency injection

Dependency Injection Frameworks

• How they make life easier

– Automatically detect and resolve dependencies (Autowiring)

– Manage object lifetime and sharing between objects (Lifetime Management)

– Allow disposing of all registered dependencies

• Lifecycle

– Register

• Perform early in application (application composition root)

• Perform all registrations at the same time

– Resolve

• Typically only resolve at the composition root

• Resolving elsewhere = Service Locator anti-pattern

– Dispose

• Dispose of DI container to ensure registered objects are disposed

• Examples

– Unity (Microsoft), Ninject, Castle Windsor, Autofac, StructureMap, …

26

Page 27: I gotta dependency on dependency injection

UnityExample

Create DI container

Register dependencies

Resolve root component

DI container and all components disposed

Page 28: I gotta dependency on dependency injection

Unity

28

Registration

• Code

– Simplest but requires recompiling when changes made

Page 29: I gotta dependency on dependency injection

Unity

29

Registration

• Code

– Simplest but requires recompiling when changes made

• XML

– More difficult (no editor) but no recompiling when changes made

Page 30: I gotta dependency on dependency injection

Unity

30

Registration

• Code

– Simplest but requires recompiling when changes made

• XML

– More difficult (no editor) but no recompiling when changes made

• Convention

– Good for large applications

Page 31: I gotta dependency on dependency injection

Unity

• Transient (default)

– New instance created for each call to Resolve

• Container Controlled (i.e. singleton)

– Shared instance when Resolve or dependency injected

• Externally Controlled

– Similar to Container Controlled (i.e. singleton)

– Weak reference kept so container does not handle disposing

• Per Thread

– One instance created per thread

31

Lifetime Managers

Page 32: I gotta dependency on dependency injection

Unity

32

Resolving

Page 33: I gotta dependency on dependency injection

Dependency Injection Frameworks

Unity (3.0) Ninject Castle Windsor Autofac StructureMap

License MS-PL Apache 2 Apache 2 MIT Apache 2

Code Configuration Yes Yes Yes Yes Yes

XML Configuration Yes Yes Yes Yes Yes

Auto Configuration Yes Yes Yes Yes Yes

Auto Wiring Yes Yes Yes Yes Yes

Lifetime Managers Yes Yes Yes Yes Yes

Interception Yes Yes Yes Yes Yes

Constructor Injection Yes Yes Yes Yes Yes

Property Injection Yes Yes Yes Yes Yes

33

Feature Comparison

• Same basic features

• Each has advanced features that set them apart

• Be aware of performance

• Research a few before choosing

Page 34: I gotta dependency on dependency injection

References

• Dependency Injection in .NET (Mark Seemann)

– http://techbus.safaribooksonline.com/book/programming/csharp/9781935182504

• Adaptive Code via C# (Gary McLean Hall)

– http://techbus.safaribooksonline.com/9780133979749/

• Intro to Inversion of Control (IoC)

– http://msdn.microsoft.com/en-us/library/ff921087.aspx

• Service Locator is an Anti-pattern (Mark Seemann)

– http://blog.ploeh.dk/2010/02/03/ServiceLocatorisanAnti-Pattern/

• Developer’s Guide to Dependency Injection Using Unity

– http://msdn.microsoft.com/en-us/library/dn223671(v=pandp.30).aspx

• IOC Framework Comparison

– http://blog.ashmind.com/2008/08/19/comparing-net-di-ioc-frameworks-part-1/

– http://www.palmmedia.de/blog/2011/8/30/ioc-container-benchmark-performance-

comparison

34


Top Related