dependency injection with unity 2.0 dmytro mindra lohika

69
Dependency Injection with Unity 2.0 Dmytro Mindra RnD Tech Lead Lohika Вторая встреча Microsoft .Net User Group Одесса, 2010

Upload: alex-tumanoff

Post on 25-May-2015

1.880 views

Category:

Documents


1 download

DESCRIPTION

Dependency injection with unity 2.0 Dmytro Mindra Lohika

TRANSCRIPT

Page 1: Dependency injection with unity 2.0 Dmytro Mindra Lohika

Dependency Injection with Unity 2.0

Dmytro MindraRnD Tech Lead

Lohika

Вторая встреча Microsoft .Net User Group Одесса, 2010

Page 2: Dependency injection with unity 2.0 Dmytro Mindra Lohika

Goal

• Get DI understanding• Get Unity 2.0 understanding• Learn how to add Unity 2.0 to your projects

Page 3: Dependency injection with unity 2.0 Dmytro Mindra Lohika

Plan

• Inversion of Control principle (IoC)• Dependency Injection pattern (DI)• Unity 2.0• Live Demo

Page 4: Dependency injection with unity 2.0 Dmytro Mindra Lohika

Problem

Page 5: Dependency injection with unity 2.0 Dmytro Mindra Lohika

Problem

We live in an age where writing software to a given set of requirements is no longer enough.

We have to maintain and change existing code.

Page 6: Dependency injection with unity 2.0 Dmytro Mindra Lohika

How?

Our solutions should be:• Modular• Testable• Adaptive to change

Page 7: Dependency injection with unity 2.0 Dmytro Mindra Lohika

Terms

• Service —An object that performs a well-defined function when called upon

• Client —Any consumer of a service; an object that calls upon a service to perform a well-understood function

Page 8: Dependency injection with unity 2.0 Dmytro Mindra Lohika

Terms

• Dependency —A specific service that is required by another object to fulfill its function.

• Dependent —A client object that needs a dependency (or dependencies) in order to perform its function.

Page 9: Dependency injection with unity 2.0 Dmytro Mindra Lohika

PRE DI APPROACHES

Page 10: Dependency injection with unity 2.0 Dmytro Mindra Lohika

Ex1:Composition

Page 11: Dependency injection with unity 2.0 Dmytro Mindra Lohika

Ex1:Composition public class SpellCheckerService{}

public class TextEditor

{ private SpellCheckerService _spellCheckerService; public TextEditor() { _spellCheckerService = new SpellCheckerService(); } } class Program { static void Main(string[] args) { TextEditor textEditor = new TextEditor(); } }

TextEditor

SpellChecker

Page 12: Dependency injection with unity 2.0 Dmytro Mindra Lohika

What’s good

• It’s simple

Page 13: Dependency injection with unity 2.0 Dmytro Mindra Lohika

What’s bad

• It’s not testable• It’s hard to maintain/change

Page 14: Dependency injection with unity 2.0 Dmytro Mindra Lohika

Ex2: Factory

Page 15: Dependency injection with unity 2.0 Dmytro Mindra Lohika

Ex2: Factory

public interface ISpellCheckerService { string CheckSpelling(); }

Page 16: Dependency injection with unity 2.0 Dmytro Mindra Lohika

Ex2: Factory

public class SpellCheckerService: ISpellCheckerService

{ public string CheckSpelling()

{ return “Real”; } }

Page 17: Dependency injection with unity 2.0 Dmytro Mindra Lohika

Ex2: Factory public class SpellCheckerFactory { private static ISpellCheckerService

_spellCheckerService = new SpellCheckerService();

public static ISpellCheckerService SpellCheckerService

{ get{ return _spellCheckerService; } set{ _spellCheckerService = value; } } }

Page 18: Dependency injection with unity 2.0 Dmytro Mindra Lohika

Ex2: Factorypublic class TextEditor{ private ISpellCheckerService _spellCheckerService; public TextEditor() { _spellCheckerService =

SpellCheckerFactory.SpellCheckerService; }

public string CheckSpelling() { return _spellCheckerService.CheckSpelling(); }}

Page 19: Dependency injection with unity 2.0 Dmytro Mindra Lohika

Ex2:Factory Unit Testingpublic class SpellCheckerServiceMock: ISpellCheckerService

{ public string CheckSpelling() { return “Mock”; } }

Page 20: Dependency injection with unity 2.0 Dmytro Mindra Lohika

Ex2:Factory Unit Testing [TestFixture] class EmailerFactoryUnitTests { [Test] public void EmailerFactoryTest() {

ISpellCheckerService mockSpellCheckerService = new SpellCheckerServiceMock();

SpellCheckerFactory.SpellCheckerService = mockSpellCheckerService;

TextEditor textEditor = new TextEditor(); Assert.AreEqual(“Mock”,

textEditor.CheckSpelling()); } }

Page 21: Dependency injection with unity 2.0 Dmytro Mindra Lohika

Ex2: Factory

SpellCheckerServ iceFactory

- SpellCheckerService: SpellCheckerService

TextEditor

+ CheckSpelling() : bool

SpellCheckerServ ice

+ CheckSpelling() : string

«interface»ISpellCheckerServ ice

+ CheckSpelling() : string

SpellCheckerServ iceMock

+ CheckSpelling() : string

getSpellCheckerService

Page 22: Dependency injection with unity 2.0 Dmytro Mindra Lohika

What changed

• TextEditor is still looking for its dependencies by itself. But now we can plug in different services without letting him know.

Page 23: Dependency injection with unity 2.0 Dmytro Mindra Lohika

What’s good

• It’s testable• It’s easier to maintain/change

Page 24: Dependency injection with unity 2.0 Dmytro Mindra Lohika

What’s bad

• You have to maintain factory or service locator• Dependent is still looking for Dependencies by

himself.• Dependencies are encapsulated and are not

obvious.

Page 25: Dependency injection with unity 2.0 Dmytro Mindra Lohika

Service Locator

Unfortunately, being a kind of Factory, Service Locators suffer from the same problemsof testability and shared state.

Page 26: Dependency injection with unity 2.0 Dmytro Mindra Lohika

Inversion of Control

Common Flow• TextEditor creates its

dependency by himself.

IoC Flow• TextEditor requests factory

to create dependency for him.

SpellCheckerServ iceFactory

- SpellCheckerService: SpellCheckerService

TextEditor

+ CheckSpelling() : bool

TextEditor

SpellChecker

Page 27: Dependency injection with unity 2.0 Dmytro Mindra Lohika

Inversion of Control

• Hollywood Principle:

Don’t call me, I’ll call you

Page 28: Dependency injection with unity 2.0 Dmytro Mindra Lohika

Inversion of Control

• IoC – is a common characteristic of frameworks.

• Inversion of Control serves as a design guideline.

• According to Martin Fowler the etymology of the phrase dates back to 1988.

Page 29: Dependency injection with unity 2.0 Dmytro Mindra Lohika

Two principles of IOC

• Main classes aggregating other classes should not depend on the direct implementation of the aggregated classes. Both the classes should depend on abstraction.

• Abstraction should not depend on details, details should depend on abstraction.

Page 30: Dependency injection with unity 2.0 Dmytro Mindra Lohika

Inversion of Controlas a Design Guideline

• Without IoC • With IoC

TextEditor

SpellChecker

TextEditor

+ CheckSpelling() : bool

SpellCheckerServ ice

+ CheckSpelling() : string

«interface»ISpellCheckerServ ice

+ CheckSpelling() : string

Loose coupling

Page 31: Dependency injection with unity 2.0 Dmytro Mindra Lohika

TIME TO INJECT !

Page 32: Dependency injection with unity 2.0 Dmytro Mindra Lohika

Ex3:Dependency Injection public class TextEditor { private readonly ISpellCheckerService

_spellCheckerService;

public TextEditor(ISpellCheckerService spellCheckerService)

{ _spellCheckerService = spellCheckerService; }

public string CheckSpelling() { return _spellCheckerService.CheckSpelling(); }

}

Page 33: Dependency injection with unity 2.0 Dmytro Mindra Lohika

Ex3: Unit Testing DI

• Almost same as for Ex2// Mock ISpellCheckerService mock = new SpellCheckerServiceMock();

// InstantiateTextEditor textEditor = new TextEditor(mock);

// CheckAssert.AreEqual(“Mock”, textEditor.CheckSpelling());

Page 34: Dependency injection with unity 2.0 Dmytro Mindra Lohika

What changed

• TextEditor lost its “Sovereignty” and is not able to resolve dependencies by himself.

Page 35: Dependency injection with unity 2.0 Dmytro Mindra Lohika

What’s good

• Dependencies are obvious.• Dependency resolution is not encapsulated.• Unit Testing got little bit easier• Architecture is much better

Page 36: Dependency injection with unity 2.0 Dmytro Mindra Lohika

What’s bad

• We are resolving dependencies manually while creating instances of TextEditor.

Page 37: Dependency injection with unity 2.0 Dmytro Mindra Lohika

Dependency Injection

SpellCheckerServ ice

+ CheckSpelling() : bool

TextEditor

+ CheckSpelling() : bool

«interface»ISpellCheckerServ ice

Page 38: Dependency injection with unity 2.0 Dmytro Mindra Lohika

Dependency Injection

• DI is IoC• Inversion of Control is too generic a term• DI pattern – describes the approach used to

lookup a dependency. • Dependency resolution is moved to

Framework.

Page 39: Dependency injection with unity 2.0 Dmytro Mindra Lohika

Ex4: Unity

Page 40: Dependency injection with unity 2.0 Dmytro Mindra Lohika

Ex4: Unity

using Microsoft.Practices.Unity;

UnityContainer container = new UnityContainer();

container.RegisterType<ISpellCheckerService, SpellCheckingService>();

TextEditor textEditor = container.Resolve<TextEditor>();

Page 41: Dependency injection with unity 2.0 Dmytro Mindra Lohika

What changed

• Unity container now resolves dependencies

Page 42: Dependency injection with unity 2.0 Dmytro Mindra Lohika

What’s good

• Automated dependency resolution

Page 43: Dependency injection with unity 2.0 Dmytro Mindra Lohika

Unity methods

• RegisterType• RegisterInstance• Resolve• BuildUp

Page 44: Dependency injection with unity 2.0 Dmytro Mindra Lohika

Ex5: Unity Configuration <configSections> <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration"/> </configSections>

<unity xmlns="http://schemas.microsoft.com/practices/2010/unity"> <alias alias="ISpellCheckerService" type="Unity.Config.ISpellCheckerService, Unity.Config" /> <alias alias="SpellCheckingService" type="Unity.Config.SpellCheckingService, Unity.Config" /> <namespace name="Unity.Config" /> <assembly name="Unity.Config" />

<container> <register type="ISpellCheckerService" mapTo="SpellCheckingService" /> </container> </unity>

Page 45: Dependency injection with unity 2.0 Dmytro Mindra Lohika

Ex5: Unity Configuration

using Microsoft.Practices.Unity;using Microsoft.Practices.Unity.Configuration;

UnityContainer container = new UnityContainer();container.LoadConfiguration();TextEditor textEditor = container.Resolve<TextEditor>();

Page 46: Dependency injection with unity 2.0 Dmytro Mindra Lohika

Dependency tree

Page 47: Dependency injection with unity 2.0 Dmytro Mindra Lohika

Ex6: Dependency treepublic interface IAdditionalDependency{}public class AdditionalDependency : IAdditionalDependency{}

public class SpellCheckingService: ISpellCheckerService {

public SpellCheckingService( IAdditionalDependency dependency){} }

Page 48: Dependency injection with unity 2.0 Dmytro Mindra Lohika

Ex6: Dependency Tree

UnityContainer container = new UnityContainer();container.RegisterType<ISpellCheckerService,

SpellCheckingService>();container.RegisterType<IAdditionalDependency,

AdditionalDependency>();TextEditor textEditor = container.Resolve<TextEditor>();

Page 49: Dependency injection with unity 2.0 Dmytro Mindra Lohika

Ex6: Dependency tree

SpellCheckerServ ice

+ CheckSpelling() : bool

TextEditor

+ CheckSpelling() : bool

«interface»ISpellCheckerServ ice

AdditionalDependency

+ CheckSpelling() : bool

«interface»IAditionalDependenct

Page 50: Dependency injection with unity 2.0 Dmytro Mindra Lohika

Injection Types

• Constructor Injection• Setter injection• Method call injection

Page 51: Dependency injection with unity 2.0 Dmytro Mindra Lohika

Ex7: Defining Injection Constructor

public class TextEditor { private readonly ISpellCheckerService _spellCheckerService;

[InjectionConstructor] public TextEditor(ISpellCheckerService spellCheckerService) { _spellCheckerService = spellCheckerService; }

public TextEditor(ISpellCheckerService spellCheckerService,string name) { _spellCheckerService = spellCheckerService; } }

Page 52: Dependency injection with unity 2.0 Dmytro Mindra Lohika

Ex8: Property Injection public class TextEditor { public ISpellCheckerService SpellCheckerService {get; set;}

[Dependency] public ISpellCheckerService YetAnotherSpellcheckerService{get;set;} } UnityContainer container = new UnityContainer(); container.RegisterType<TextEditor>(new InjectionProperty("SpellCheckerService")); container.RegisterType<ISpellCheckerService, SpellCheckingService>(); TextEditor textEditor = container.Resolve<TextEditor>();

Page 53: Dependency injection with unity 2.0 Dmytro Mindra Lohika

Ex9: Method call injection public class TextEditor { public ISpellCheckerService SpellcheckerService {get; set;}

[InjectionMethod] public void Initialize (ISpellCheckerService spellcheckerService) { _spellCheckerService = spellcheckerService; } }UnityContainer container = new UnityContainer();//container.RegisterType<TextEditor>(

new InjectionMethod("SpellcheckerService"));container.RegisterType<ISpellCheckerService, SpellCheckingService>();TextEditor textEditor = container.Resolve<TextEditor>();

Page 54: Dependency injection with unity 2.0 Dmytro Mindra Lohika

Lifetime Managers

• TransientLifetimeManagerReturns a new instance of the requested type for each call. (default behavior)

• ContainerControlledLifetimeManagerImplements a singleton behavior for objects. The object is disposed of when you dispose of the container.

Page 55: Dependency injection with unity 2.0 Dmytro Mindra Lohika

Lifetime Managers

• ExternallyControlledLifetimeManagerImplements a singleton behavior but the container doesn't hold a reference to object which will be disposed of when out of scope.

• HierarchicalifetimeManagerImplements a singleton behavior for objects. However, child containers don't share instances with parents.

Page 56: Dependency injection with unity 2.0 Dmytro Mindra Lohika

Lifetime Managers

• PerResolveLifetimeManagerImplements a behavior similar to the transient lifetime manager except that instances are reused across build-ups of the object graph.

• PerThreadLifetimeManagerImplements a singleton behavior for objects but limited to the current thread.

Page 57: Dependency injection with unity 2.0 Dmytro Mindra Lohika

Ex10: Unity Singleton

UnityContainer container = new UnityContainer();container.RegisterType<ISpellCheckerService, SpellCheckingService>(new ContainerControlledLifetimeManager());TextEditor textEditor = container.Resolve<TextEditor>();

Page 58: Dependency injection with unity 2.0 Dmytro Mindra Lohika

Container Hierarchy

Page 59: Dependency injection with unity 2.0 Dmytro Mindra Lohika

Unity Limitations

• When your objects and classes have no dependencies on other objects or classes.

• When your dependencies are very simple and do not require abstraction.

Page 60: Dependency injection with unity 2.0 Dmytro Mindra Lohika

What Unity stands for

For• Wiring framework

components

Not for• Wiring small parts

Page 61: Dependency injection with unity 2.0 Dmytro Mindra Lohika

Performance

Page 62: Dependency injection with unity 2.0 Dmytro Mindra Lohika

Performance

Page 63: Dependency injection with unity 2.0 Dmytro Mindra Lohika

Performance

Page 64: Dependency injection with unity 2.0 Dmytro Mindra Lohika

.NET DI Frameworks

• Unity 2.0• AutoFac 2.3.2• StructureMap 2.6.1• Castle Windsor 2.1• Ninject 2.0

Page 65: Dependency injection with unity 2.0 Dmytro Mindra Lohika

Additional reading

Page 66: Dependency injection with unity 2.0 Dmytro Mindra Lohika

Additional reading

Page 67: Dependency injection with unity 2.0 Dmytro Mindra Lohika

Live Demo

Page 68: Dependency injection with unity 2.0 Dmytro Mindra Lohika

QUESTIONS ?

Page 69: Dependency injection with unity 2.0 Dmytro Mindra Lohika

THANK YOU !