IOC in Unity

Preview:

Citation preview

IoC in Microsoft Unity

Francesco Garavaglia

03/2016

Agenda The Problem

Composition by Examples

Inversion of Control (IoC)

Dependency Injection Microsoft

Unity

2

What problems

are we trying to

solve?

3

4

The 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.

Code quality ( What’s Bad ) R.Martin 1996

- Rigid (hard to modify)

- Fragile ( errors occur on almost every change)

- Immobile (not reusable)

The Problem

How?Our solutions should be:

• Modular

• Testable

• Adaptive to change

• Whatever you want

5

How?Our solutions should be:

• Modular

• Testable

• Adaptive to change

• Whatever you want

6

7

We need a glossary

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

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.

The Problem

Composition:

OLD SCHOOL

8

9

Ex1:CompositionComposition by Examples

10

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

Composition by Examples

11

Ex1: Composition

• SimpleWhat is Good

• It’s not testable

• It’s hard to maintain/change

What is Bad

Composition by Examples

Composition:

NEW SCHOOL

12

13

Better approach

TextEditor

+ CheckSpelling() : bool

SpellCheckerServ ice

+ CheckSpelling() : string

«interface»

ISpellCheckerServ ice

+ CheckSpelling() : string

Dependency Inversion

A.High-level modules should not

depend on low-level modules. Both

should depend on abstractions.

B. Abstractions should not depend

upon details. Details should depend

upon abstractions.

Robert C. Martin 1996

Composition by Examples

14

Context

Granny

+ Eat() : void

«interface»

IAppleProv ider

+ GetApple() : IApple

RedAppleProv ider

+ GetApple() : IApple

GoldenAppleProv ider

+ GetApple() : IApple

«interface»

IPillProv ider

ConcretePillProv ider

Context

Composition by Examples

15

Ex2:Loose Coupling

public class TextEditor

{

private readonly ISpellCheckerService _spellCheckerService;

public TextEditor(ISpellCheckerService spellCheckerService)

{

_spellCheckerService = spellCheckerService;

}

public string CheckSpelling()

{

return _spellCheckerService.CheckSpelling();

}

}

Composition by Examples

16

Ex2: Unit Testing

// Mock

ISpellCheckerService mock = new SpellCheckerServiceMock();

// Instantiate

TextEditor textEditor = new TextEditor(mock);

// Check

Assert.AreEqual(“Mock”, textEditor.CheckSpelling());

Composition by Examples

17

Ex2: Good vs Bad

• Dependencies are obvious.

• Dependency resolution is not encapsulated.

• Unit Testing is applicable

• Architecture is much better

What is Good

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

What is Bad

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

Composition by Examples

18

Ex3: Using FactoryComposition by Examples

19

20

21

22

23

24

25

Factory

TextEditorFactory

+ GetEnglishTextEditor() : TextEditor

+ GetFrenchTextEditor() : TextEditor

TextEditor

FrenchSpellCheckerServ ice

«interface»

ISpellCheckerServ ice

EnglishSpellCheckerServ ice

Composition by Examples

26

What changed

Any required combination of Text Editor and Spell Checking Service is created by object factory.

•It’s testable

•No manual wiring

What is Good

•You have to maintain factory or service locator

•The more combinations the more methods we have in factory.

•Your code knows about the specific factory or factory interface. This means that infrastructure logic is mixed with business logic.

•Factory may have states.

What is Bad

Composition by Examples

27

Ex4: Service Locator

Unfortunately, being a kind of Factory, Service Locators suffer from the same problems

of testability and shared state.

Composition by Examples

28

What are we looking for?Composition by Examples

Inversion of

Control

HOLLYWOOD PRINCIPLE:

DON’T CALL ME, I’LL CALL YOU

29

30

Inversion of Control

IoC – is a common characteristic of

frameworks.

According to Martin Fowler the etymology of

the phrase dates back to 1988.

Inversion of Control

31

Dependency Injection

DI is a kind of 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.

Inversion of Control

32

SpellCheckerServ ice

+ CheckSpelling() : bool

TextEditor

+ CheckSpelling() : bool

«interface»

ISpellCheckerServ ice

We have already prepared basis

Loosely

coupled

structure

Inversion of Control

It’s time to

introduce new

role: Injector

Injector(sometimes referred to as

a provider or container)

33

Unity

34

35

Ex5: Unity

using Microsoft.Practices.Unity;

UnityContainer container = new UnityContainer();

container.RegisterType<ISpellCheckerService, SpellCheckingService>();

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

DI with Unity

36

What changed

Unity container now resolves dependencies

•Automated dependency resolution

•Business logic and infrastructure are decoupled.

What is Good

What is Bad

DI with Unity

37

Injection Types

Interface injection (by Martin Fowler)

Constructor Injection (by Martin Fowler)

Setter injection (by Martin Fowler)

Method call injection (Unity)

Method decorator injection (Guice)

DI with Unity

38

Unity Configuration

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

actices.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>

DI with Unity

39

Unity Configuration

using Microsoft.Practices.Unity;

using Microsoft.Practices.Unity.Configuration;

UnityContainer container = new UnityContainer();

container.LoadConfiguration();

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

DI with Unity

40

Dependency treeDI with Unity

41

Dependency tree

public interface IAdditionalDependency{}

public class AdditionalDependency : IAdditionalDependency{}

public class SpellCheckingService: ISpellCheckerService {

public SpellCheckingService( IAdditionalDependency dependency){}

}

UnityContainer container = new UnityContainer();

container.RegisterType<ISpellCheckerService, SpellCheckingService>();

container.RegisterType<IAdditionalDependency, AdditionalDependency>();

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

DI with Unity

42

Dependency tree

SpellCheckerServ ice

+ CheckSpelling() : bool

TextEditor

+ CheckSpelling() : bool

«interface»

ISpellCheckerServ ice

AdditionalDependency

+ CheckSpelling() : bool

«interface»

IAditionalDependenct

DI with Unity

43

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;}

}

DI with Unity

44

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>();

DI with Unity

45

Method call injection

public class TextEditor{

public ISpellCheckerService SpellcheckerService {get; set;}

public void Initialize (ISpellCheckerService spellcheckerService){

_spellCheckerService = spellcheckerService;}

}

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

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

DI with Unity

46

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.

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.

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.

DI with Unity

47

Unity Singleton

UnityContainer container = new UnityContainer();

container.RegisterType<ISpellCheckerService, SpellCheckingService>(new

ContainerControlledLifetimeManager());

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

DI with Unity

48

Container HierarchyDI with Unity

49

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.

DI with Unity

50

References

Martin Fowler – Dependency Injection

http://martinfowler.com/articles/injection.html

R. Martin - Dependency Inversion principle

http://www.objectmentor.com/resources/articles/dip.pdf

Developer's Guide to Dependency Injection Using Unity

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

ThanksFRANCESCO.GARAVAGLIA@GMAIL.COM

Recommended