manage software dependencies with ioc and aop

49
Manage software dependencies Manage software dependencies with IoC and AOP with IoC and AOP Stefano Leli Stefano Leli 14° Workshop 14° Workshop DotNetMarche DotNetMarche Friday 16 Friday 16 th th April 2010 April 2010 @sleli @sleli [email protected] [email protected]

Upload: stefano-leli

Post on 06-May-2015

1.036 views

Category:

Technology


0 download

DESCRIPTION

Manage software dependencies with io c and aop

TRANSCRIPT

Page 1: Manage software dependencies with ioc and aop

Manage software Manage software dependencies with IoC and dependencies with IoC and

AOPAOP

Stefano LeliStefano Leli

14° Workshop 14° Workshop DotNetMarcheDotNetMarcheFriday 16Friday 16thth April 2010 April 2010

@sleli@sleli

[email protected]@gmail.com

Page 2: Manage software dependencies with ioc and aop

Software DependenciesSoftware Dependencies

Service LocatorService Locator

Inversion of ControlInversion of Control

Dependency InjectionDependency Injection

Aspect Oriented ProgrammingAspect Oriented Programming

AgendaAgenda

Page 3: Manage software dependencies with ioc and aop

What is a What is a Dependency?Dependency?

Page 4: Manage software dependencies with ioc and aop

ClassA

+RequestService()

ClassB

public RequestService(){ ClassB b = new ClassB() b.DoService();}

DependenciesDependencies

dependent

+DoService()

Page 5: Manage software dependencies with ioc and aop

Layer DependenciesLayer Dependencies

Presentation Layer

Business Layer

Data Access Layer

Depends on

High-level modules High-level modules should not depend on should not depend on

low-level modules. low-level modules. Both should depend Both should depend

on abstractionson abstractionsRobert C. MartinRobert C. Martin

DB

Depends on

Depends on

Page 6: Manage software dependencies with ioc and aop

Why dependencies are evil?Why dependencies are evil?

Tight coupling of software componentsTight coupling of software components hard to change because every change affects hard to change because every change affects

too many other parts of the system (Rigidity)too many other parts of the system (Rigidity) When you make a change, unexpected parts of When you make a change, unexpected parts of

the system break. (Fragility)the system break. (Fragility) hard to reuse in another application. hard to reuse in another application.

(Immobility)(Immobility)

Software becomes hard to maintainSoftware becomes hard to maintain

Difficult to isolate when testingDifficult to isolate when testing

Page 7: Manage software dependencies with ioc and aop

ScenarioScenario

Page 8: Manage software dependencies with ioc and aop

Copier ExampleCopier Example

Copier

+PerformCopy()

Keyboard

+ReadFromKB(c : char)

Video

+WriteToVideo() : char

Page 9: Manage software dependencies with ioc and aop

class Copierclass Copier

{{

Keyboard _reader;Keyboard _reader;

Video _writer;Video _writer;

public Copier()public Copier()

{{

_reader = new Keyboard();_reader = new Keyboard();

_writer = new Video();_writer = new Video();

}}

public void PerformCopy()public void PerformCopy()

{{

int chr;int chr;

while ( (chr = _reader.ReadFromKeyboard() ) != '\r')while ( (chr = _reader.ReadFromKeyboard() ) != '\r')

_writer.WriteToVideo(chr);_writer.WriteToVideo(chr);

}}

}}

class Keyboardclass Keyboard

{{

public int ReadFromKeyboard()public int ReadFromKeyboard()

{ {

return Console.ReadKey(true).KeyChar;return Console.ReadKey(true).KeyChar;

}}

}}

class Videoclass Video

{{

public void WriteToVideo(int chr)public void WriteToVideo(int chr)

{{

Console.Write((char)chr);Console.Write((char)chr);

}}

}}

Copier ExampleCopier Example

Page 10: Manage software dependencies with ioc and aop

class Copierclass Copier

{{

Keyboard _reader;Keyboard _reader;

Video _writer;Video _writer;

public Copier()public Copier()

{{

__reader = new Keyboard();reader = new Keyboard();

_writer = new Video();_writer = new Video();

}}

public void PerformCopy()public void PerformCopy()

{{

int chr;int chr;

while ( (chr = _reader.ReadFromKeyboard() ) != '\r')while ( (chr = _reader.ReadFromKeyboard() ) != '\r')

_writer.WriteToVideo(chr);_writer.WriteToVideo(chr);

}}

}}

class Keyboardclass Keyboard

{{

public int ReadFromKeyboard()public int ReadFromKeyboard()

{ {

return Console.ReadKey(true).KeyChar;return Console.ReadKey(true).KeyChar;

}}

}}

class Videoclass Video

{{

public void WriteToVideo(int chr)public void WriteToVideo(int chr)

{{

Console.Write((char)chr);Console.Write((char)chr);

}}

}}

Copier ExampleCopier Example

Problem

Page 11: Manage software dependencies with ioc and aop

Program to an Program to an interface, not an interface, not an implementationimplementation

Page 12: Manage software dependencies with ioc and aop

Copier ExampleCopier Example

<<create>>

<<create>>

IWriterIReader

Copier

+PerformCopy()

Keyboard

+Read(c : char)

Video

+Write() : char

Concrete class should depend on abstraction

Robert Martin

Page 13: Manage software dependencies with ioc and aop

class Copierclass Copier

{{

IReaderIReader _reader; _reader;

IWriterIWriter _writer; _writer;

public Copier()public Copier()

{{

_reader = new Keyboard();_reader = new Keyboard();

_writer = new Video();_writer = new Video();

}}

public void PerformCopy()public void PerformCopy()

{{

int chr;int chr;

while ( (chr = _reader.Read() ) != '\r')while ( (chr = _reader.Read() ) != '\r')

_writer.Write(chr);_writer.Write(chr);

}}

}}

class Keyboard class Keyboard : IReader: IReader

{{

public int public int ReadRead()()

{ {

return Console.ReadKey(true).KeyChar;return Console.ReadKey(true).KeyChar;

}}

}}

class Video class Video : IWriter: IWriter

{{

public void public void WriteWrite(int chr)(int chr)

{{

Console.Write((char)chr);Console.Write((char)chr);

}}

}}

Copier ExampleCopier Example

Page 14: Manage software dependencies with ioc and aop

class Copierclass Copier

{{

IReaderIReader _reader; _reader;

IWriterIWriter _writer; _writer;

public Copier()public Copier()

{{

_reader = new Keyboard();_reader = new Keyboard();

_writer = new Video();_writer = new Video();

}}

public void PerformCopy()public void PerformCopy()

{{

int chr;int chr;

while ( (chr = _reader.Read() ) != '\r')while ( (chr = _reader.Read() ) != '\r')

_writer.Write(chr);_writer.Write(chr);

}}

}}

class Keyboard class Keyboard : IReader: IReader

{{

public int public int ReadRead()()

{ {

return Console.ReadKey(true).KeyChar;return Console.ReadKey(true).KeyChar;

}}

}}

class Video class Video : IWriter: IWriter

{{

public void public void WriteWrite(int chr)(int chr)

{{

Console.Write((char)chr);Console.Write((char)chr);

}}

}}

Copier ExampleCopier Example

Problem

Dependencies resolution is still here!!!

Page 15: Manage software dependencies with ioc and aop

Towards Towards

DecouplingDecoupling

Page 16: Manage software dependencies with ioc and aop

<<create>>

Using a FactoryUsing a Factory

<<create>>

IWriterIReader

Copier

Keyboard

+Read(c : char)

Video

+Write() : char

ReaderFactory

+GetInstance() : IReader

+Copier(r : IReader, w : IWriter)+PerformCopy()

WriterFactory

+GetInstance() : IWriter

Page 17: Manage software dependencies with ioc and aop

class Copierclass Copier

{{

IReader _reader;IReader _reader;

IWriter _writer;IWriter _writer;

public Copier()public Copier()

{{

__reader = ReaderFactory.reader = ReaderFactory.GetInstanceGetInstance();();

_writer = WriterFactory._writer = WriterFactory.GetInstanceGetInstance();();

}}

public void PerformCopy()public void PerformCopy()

{{

int chr;int chr;

while ( (chr = _reader.Read() ) != '\r')while ( (chr = _reader.Read() ) != '\r')

_writer.Write(chr);_writer.Write(chr);

}}

}}

class ReaderFactoryclass ReaderFactory

{{

public static IReader GetInstance()public static IReader GetInstance()

{{

return new Keyboard();return new Keyboard();

}}

}}

class WriterFactoryclass WriterFactory

{{

public static IWriter GetInstance()public static IWriter GetInstance()

{{

return new Video();return new Video();

}}

}}

Using a FactoryUsing a Factory

Page 18: Manage software dependencies with ioc and aop

class Copierclass Copier

{{

IReader _reader;IReader _reader;

IWriter _writer;IWriter _writer;

public Copier()public Copier()

{{

_reader = ReaderFactory._reader = ReaderFactory.GetInstanceGetInstance();();

_writer = WriterFactory._writer = WriterFactory.GetInstanceGetInstance();();

}}

public void PerformCopy()public void PerformCopy()

{{

int chr;int chr;

while ( (chr = _reader.Read() ) != '\r')while ( (chr = _reader.Read() ) != '\r')

_writer.Write(chr);_writer.Write(chr);

}}

}}

class ReaderFactoryclass ReaderFactory

{{

public static IReader GetInstance()public static IReader GetInstance()

{{

return new Keyboard();return new Keyboard();

}}

}}

class WriterFactoryclass WriterFactory

{{

public static IWriter GetInstance()public static IWriter GetInstance()

{{

return new Video();return new Video();

}}

}}

Using a FactoryUsing a Factory

We have just moved the problem!!!

Problem

Page 19: Manage software dependencies with ioc and aop

<<create>> <<create>>

IWriterIReader

Copier

Keyboard

+Read(c : char)

Video

+Write() : char

+PerformCopy()

ServiceLocator

+Lookup() : Object+RegisterService(o : Object)

_instance : ServiceLocator

Service LocatorService Locator

Page 20: Manage software dependencies with ioc and aop

<<create>> <<create>>

IWriterIReader

Copier

Keyboard

+Read(c : char)

Video

+Write() : char

+PerformCopy()

ServiceLocator

+Lookup() : Object+RegisterService(o : Object)

_instance : ServiceLocator

Service LocatorService Locator

Page 21: Manage software dependencies with ioc and aop

Service LocatorService Locator

class ServiceLocatorclass ServiceLocator

{{

/* Singleton instance *//* Singleton instance */

private static ServiceLocator _instance; private static ServiceLocator _instance;

public static void Load(ServiceLocator arg)public static void Load(ServiceLocator arg)

{{

_instance = arg;_instance = arg;

}}

/* Storing and Retrieve services *//* Storing and Retrieve services */

private Dictionary<string, Object> _services = new Dictionary<string, Object>();private Dictionary<string, Object> _services = new Dictionary<string, Object>();

public Object RegisterService(String key)public Object RegisterService(String key)

{{

return _instance._services[key];return _instance._services[key];

}}

public static void Lookup(String key, Object service)public static void Lookup(String key, Object service)

{{

_services.Add(key, service);_services.Add(key, service);

}}

}}

Page 22: Manage software dependencies with ioc and aop

Service LocatorService Locator

class Copierclass Copier

{{

IReader _reader;IReader _reader;

IWriter _writer;IWriter _writer;

public Copier()public Copier()

{{

_reader = (IReader)ServiceLocator.Lookup("reader");_reader = (IReader)ServiceLocator.Lookup("reader");

_writer = (IWriter)ServiceLocator.Lookup("writer"); ;_writer = (IWriter)ServiceLocator.Lookup("writer"); ;

}}

public void PerformCopy()public void PerformCopy()

{{

int chr;int chr;

while ( (chr = _reader.Read() ) != '\r')while ( (chr = _reader.Read() ) != '\r')

_writer.Write(chr);_writer.Write(chr);

}}

}}

/* /* Configure Service Locator methodConfigure Service Locator method*/*/

private void configureLocator()private void configureLocator()

{{

ServiceLocator locator = new ServiceLocator(); ServiceLocator locator = new ServiceLocator();

locator.LoadService("reader", new Keyboard());locator.LoadService("reader", new Keyboard());

locator.LoadService("writer", new Video());locator.LoadService("writer", new Video());

ServiceLocator.Load(locator);ServiceLocator.Load(locator);

}}

Page 23: Manage software dependencies with ioc and aop

ProPro Help to avoid couplingHelp to avoid coupling Centralize dependencies resolutionCentralize dependencies resolution

ConsCons Introduce dependencies with the Introduce dependencies with the

locatorlocator Difficult to testDifficult to test

Service LocatorService Locator

Page 24: Manage software dependencies with ioc and aop

IInversion nversion

oof f

CControlontrol

Page 25: Manage software dependencies with ioc and aop

Inversion of ControlInversion of Control, or , or IoCIoC, is an , is an abstract principle describing an aspect of abstract principle describing an aspect of some software architecture designs in some software architecture designs in which the flow of control of a system is which the flow of control of a system is inverted in comparison to traditional inverted in comparison to traditional programming.programming.

Hollywood PrincipleHollywood Principle

““don't call us, we'll call you.”don't call us, we'll call you.”

There are many implementations of IoC, There are many implementations of IoC, Dependency Injections is one of there.Dependency Injections is one of there.

What is IoC?What is IoC?

Page 26: Manage software dependencies with ioc and aop

Technique for supplying an external Technique for supplying an external dependency to a software component.dependency to a software component.

Implemented by a Container (IoC)Implemented by a Container (IoC) Creates and assembles component/objects and Creates and assembles component/objects and

manages their lifecyclemanages their lifecycle Generally configured by coding or external fileGenerally configured by coding or external file

Three forms of injectionThree forms of injection Constructor InjectionConstructor Injection Setter InjectionSetter Injection Interface InjectionInterface Injection

What is Dependency Injection?What is Dependency Injection?

Page 27: Manage software dependencies with ioc and aop

IoC Container

IWriterIReader

Copier

Keyboard

+Read(c : char)

Video

+Write() : char

+Copier(r : IReader, w : IWriter)+PerformCopy()

Page 28: Manage software dependencies with ioc and aop

<<create>> <<create>>

IoC Container

<<create>>

IWriterIReader

Copier

Keyboard

+Read(c : char)

Video

+Write() : char

IoCContainer

+Copier(r : IReader, w : IWriter)+PerformCopy()

XMLConfi

g

Page 29: Manage software dependencies with ioc and aop

DI: Constructor InjectionDI: Constructor Injection

class Copierclass Copier

{{

IReader _reader;IReader _reader;

IWriter _writer;IWriter _writer;

public Copier(public Copier(IReader reader, IWriter writerIReader reader, IWriter writer))

{{

_reader = reader;_reader = reader;

_writer = writer;_writer = writer;

}}

public void PerformCopy()public void PerformCopy()

{{

int chr;int chr;

while ( (chr = _reader.Read() ) != '\r')while ( (chr = _reader.Read() ) != '\r')

_writer.Write(chr);_writer.Write(chr);

}}

}}

To prefer in case ofMandatory Dependencies

Page 30: Manage software dependencies with ioc and aop

DI: Setter InjectionDI: Setter Injection

class Copierclass Copier

{ {

private IReader _reader;private IReader _reader;

public IReader Readerpublic IReader Reader

{{

set{_reader = value;}set{_reader = value;}

}}

private IWriter _writerprivate IWriter _writer;;

public IWriter Writerpublic IWriter Writer

{{

set{_writer = value;}set{_writer = value;}

}}

public void PerformCopy()public void PerformCopy()

{{

int chr;int chr;

while ((chr = _reader.Read()) != '\r')while ((chr = _reader.Read()) != '\r')

_writer.Write(chr);_writer.Write(chr);

}}

}} To prefer in case ofOptional Dependencies

Page 31: Manage software dependencies with ioc and aop

DI: Interface InjectionDI: Interface Injection

class Copierclass Copier

{ {

private IReader _reader;private IReader _reader;

public void InjectReader(IReader reader)public void InjectReader(IReader reader)

{ {

_reader = reader;_reader = reader;

}}

private IWriter _writer;private IWriter _writer;

public void InjectWriter(IWriter writer)public void InjectWriter(IWriter writer)

{ {

_writer = writer; _writer = writer;

}}

public void PerformCopy()public void PerformCopy()

{{

int chr;int chr;

while ((chr = _reader.Read()) != '\r')while ((chr = _reader.Read()) != '\r')

_writer.Write(chr);_writer.Write(chr);

}}

}}

interface IReaderInjectinterface IReaderInject

{{

void injectReader(IReader reader); void injectReader(IReader reader);

}}

interface IWriterInjectinterface IWriterInject

{{

void injectWriter(IWriter reader); void injectWriter(IWriter reader);

}}

Quite Never Used

Page 32: Manage software dependencies with ioc and aop

ProPro High Decoupling levelHigh Decoupling level Completely transparent to the Domain Completely transparent to the Domain

ModelModel High ConfigurableHigh Configurable Integrated with lots of frameworkIntegrated with lots of framework

ConsCons Difficult to understand by newbieDifficult to understand by newbie Complex to debugComplex to debug

DI: ConsiderationDI: Consideration

Page 33: Manage software dependencies with ioc and aop

AAspectspect

OOriented riented

PProgrammingrogramming

Page 34: Manage software dependencies with ioc and aop

AOP is a programming paradigmAOP is a programming paradigm

AOP is a new way of thinking about AOP is a new way of thinking about software designsoftware design

Enhance OOP in separating concerns Enhance OOP in separating concerns to improve modularizationto improve modularization

OOP modularizes concernsOOP modularizes concerns

AOP addresses AOP addresses cross-cutting cross-cutting concernsconcerns

What is AOP?What is AOP?

Page 35: Manage software dependencies with ioc and aop

Separation of ConcernSeparation of Concern

Searching

Booking

Payment

Page 36: Manage software dependencies with ioc and aop

Separation of ConcernSeparation of Concern

Booking PaymentSearching

OOPSearching

Booking

Payment

Reduce software complexityReduce software complexity

Limit the impact of changeLimit the impact of change

Facilitate reuseFacilitate reuse

Simplify components Simplify components integrationintegration

Page 37: Manage software dependencies with ioc and aop

Crosscutting ConcernCrosscutting Concern

Booking

SecurityLogging

Payment

SecurityLogging

Searching

SecurityLogging

OOP

Crosscutting concerns are functionalities that span Crosscutting concerns are functionalities that span multiple modulesmultiple modules SecuritySecurity LoggingLogging Transaction ManagementTransaction Management ……

Hard to model with traditional OOP approachHard to model with traditional OOP approach Code Scattering Code Scattering Code TanglingCode Tangling

Crosscutting Concerns

Searching

Booking

Payment

Page 38: Manage software dependencies with ioc and aop

Crosscutting ConcernCrosscutting Concern

Booking PaymentSearching

Security Logging

AOP

Booking

SecurityLogging

Payment

SecurityLogging

Searching

SecurityLogging

OOP

Crosscutting Concerns

Searching

Booking

Payment

Page 39: Manage software dependencies with ioc and aop

Object_BObject_A

How it works…How it works…

Object Oriented Flow

Page 40: Manage software dependencies with ioc and aop

Aspect

Object_BObject_A

How it works…How it works…

advice

Object Oriented Flow

Aspect Oriented Flow

pointcut = method_B

Target Object = Object_B

jointpoint = method invocation

Page 41: Manage software dependencies with ioc and aop

Aspect

Object_BObject_A

How it works…How it works…

advice

Object Oriented Flow

Aspect Oriented Flow

pointcut = method_B

Target Object = Object_B

jointpoint = method invocation

AspectAspect Equivalent to class in OOPEquivalent to class in OOP Used to describe a Used to describe a

Crosscutting ConcernCrosscutting Concern

Page 42: Manage software dependencies with ioc and aop

Aspect

Object_BObject_A

How it works…How it works…

advice

Object Oriented Flow

Aspect Oriented Flow

pointcut = method_B

Target Object = Object_B

jointpoint = method invocation

Join PointJoin Point Well-defined point during the Well-defined point during the

execution of a program (e.g. execution of a program (e.g. method invocation, attribute method invocation, attribute access, exception handling,access, exception handling,…)…)

Page 43: Manage software dependencies with ioc and aop

Aspect

Object_BObject_A

How it works…How it works…

advice

Object Oriented Flow

Aspect Oriented Flow

pointcut = method_B

Target Object = Object_B

jointpoint = method invocation

AdviceAdvice action taken by an aspect at action taken by an aspect at

a particular join pointa particular join point

Page 44: Manage software dependencies with ioc and aop

Aspect

Object_BObject_A

How it works…How it works…

advice

Object Oriented Flow

Aspect Oriented Flow

pointcut = method_B

Target Object = Object_B

jointpoint = method invocation

PointcutPointcut Predicate that matches join Predicate that matches join

pointspoints Advice is associated with a Advice is associated with a

pointcut expression and runs pointcut expression and runs at any join point matched by at any join point matched by the pointcutthe pointcut

Page 45: Manage software dependencies with ioc and aop

Aspect

Object_BObject_A

How it works…How it works…

advice

Object Oriented Flow

Aspect Oriented Flow

pointcut = method_B

Target Object = Object_B

jointpoint = method invocation

Target ObjectTarget Object Also called Advised ObjectAlso called Advised Object Object being advised by one Object being advised by one

or more aspectsor more aspects

Page 46: Manage software dependencies with ioc and aop

Aspect

Object_BObject_A

advice

Object Oriented Flow

Aspect Oriented Flow

pointcut = method_B

Target Object = Object_B

jointpoint = method invocation

Wea

ving

WeavingWeaving Run-Time WeavingRun-Time Weaving Compile-Time WeavingCompile-Time Weaving

… … behind the scenesbehind the scenes

Page 47: Manage software dependencies with ioc and aop

ReferencesReferences

Martin FowlerMartin Fowler Inversion of Control Containers and the Inversion of Control Containers and the

Dependency Injection patternDependency Injection pattern

Robert C. MartinRobert C. Martin The Dependency Inversion PrincipleThe Dependency Inversion Principle

AOP AllianceAOP Alliance

Page 48: Manage software dependencies with ioc and aop

Questions?Questions?

Page 49: Manage software dependencies with ioc and aop

Slide and MaterialsSlide and Materials

www.dotnetmarche.orgwww.dotnetmarche.org

Grazie!Grazie!