Upload
stefano-leli
View
1.036
Download
0
Tags:
Embed Size (px)
DESCRIPTION
Manage software dependencies with io c and aop
Citation preview
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
Software DependenciesSoftware Dependencies
Service LocatorService Locator
Inversion of ControlInversion of Control
Dependency InjectionDependency Injection
Aspect Oriented ProgrammingAspect Oriented Programming
AgendaAgenda
What is a What is a Dependency?Dependency?
ClassA
+RequestService()
ClassB
public RequestService(){ ClassB b = new ClassB() b.DoService();}
DependenciesDependencies
dependent
+DoService()
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
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
ScenarioScenario
Copier ExampleCopier Example
Copier
+PerformCopy()
Keyboard
+ReadFromKB(c : char)
Video
+WriteToVideo() : char
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
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
Program to an Program to an interface, not an interface, not an implementationimplementation
Copier ExampleCopier Example
<<create>>
<<create>>
IWriterIReader
Copier
+PerformCopy()
Keyboard
+Read(c : char)
Video
+Write() : char
Concrete class should depend on abstraction
Robert Martin
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
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!!!
Towards Towards
DecouplingDecoupling
<<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
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
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
<<create>> <<create>>
IWriterIReader
Copier
Keyboard
+Read(c : char)
Video
+Write() : char
+PerformCopy()
ServiceLocator
+Lookup() : Object+RegisterService(o : Object)
_instance : ServiceLocator
Service LocatorService Locator
…
<<create>> <<create>>
IWriterIReader
Copier
Keyboard
+Read(c : char)
Video
+Write() : char
+PerformCopy()
ServiceLocator
+Lookup() : Object+RegisterService(o : Object)
_instance : ServiceLocator
Service LocatorService Locator
…
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);
}}
}}
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);
}}
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
IInversion nversion
oof f
CControlontrol
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?
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?
IoC Container
IWriterIReader
Copier
Keyboard
+Read(c : char)
Video
+Write() : char
+Copier(r : IReader, w : IWriter)+PerformCopy()
<<create>> <<create>>
IoC Container
<<create>>
IWriterIReader
Copier
Keyboard
+Read(c : char)
Video
+Write() : char
IoCContainer
…
+Copier(r : IReader, w : IWriter)+PerformCopy()
XMLConfi
g
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
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
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
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
AAspectspect
OOriented riented
PProgrammingrogramming
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?
Separation of ConcernSeparation of Concern
Searching
Booking
Payment
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
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
Crosscutting ConcernCrosscutting Concern
Booking PaymentSearching
Security Logging
AOP
Booking
SecurityLogging
Payment
SecurityLogging
Searching
SecurityLogging
OOP
Crosscutting Concerns
Searching
Booking
Payment
Object_BObject_A
How it works…How it works…
Object Oriented Flow
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
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
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,…)…)
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
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
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
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
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
Questions?Questions?
Slide and MaterialsSlide and Materials
www.dotnetmarche.orgwww.dotnetmarche.org
Grazie!Grazie!