An Introduction to Aspect-Oriented Programming in Microsoft .NET.<br />Produce Cleaner Code with Aspect-Oriented Programmi...
AOP Facts<br />
Agenda<br />The Problem with Conventional Programming<br />What is AOP?<br />Why AOP?<br />PostSharp Features<br />Compari...
The Problem with Conventional Programming<br />Part 1<br />
In the beginning           there was nothing.<br />public class RentalService<br />{<br />}<br />
Customer said: let there be business value.<br />publicclassRentalService<br />{<br />publicvoid RentMovie(Guid movieId, G...
publicclassRentalService<br />{<br />privatestaticreadonlyTraceSource Trace =<br />newTraceSource(typeof (RentalService).F...
publicclassRentalService<br />{<br />privatestaticreadonlyTraceSource Trace =<br />newTraceSource(typeof (RentalService).F...
publicclassRentalService<br />{<br />privatestaticreadonlyTraceSource Trace =<br />newTraceSource(typeof (RentalService).F...
publicclassRentalService<br />{<br />privatestaticreadonlyTraceSource Trace =<br />newTraceSource(typeof (RentalService).F...
We want a nice separation of concerns (assembly > namespace > class > method)<br />OOP forces us to write crap!<br />Code ...
Security<br />Exception Handling<br />Tracing<br />Monitoring<br />Transaction<br />Data Binding<br />Thread Sync<br />Cac...
Encapsulating Infrastructure Concerns?<br />
Aspects!<br />
Strengthen Applications With Aspects<br />Show Me!<br />
Show Me!<br />1. Add a reference to PostSharp.dll<br />
Show Me!<br />2. Write an aspect {Demo}<br />
Show Me!<br />3. Apply the aspect {Demo}<br />
Show Me!<br />How does it work?<br />1. Source<br />2. Compiler<br />3. PostSharp<br />4. Run Time<br />
The Idea Behind AOP<br />Part 2<br />
Problem Domain<br />Cross-Cutting Concerns<br />Solution Domain<br />Separation of Concerns<br />
What is AOP?<br />An extension of (not an alternative to) OOP that addresses the issue of cross-cutting concerns by provid...
15 Years of AOP History<br />Hype Years<br />Productivity Years<br />Research Years<br />
Why You Should Care<br />The benefits of aspect-oriented programming<br />
The benefits of aspect-oriented programming<br />Decrease Development Costs<br />WriteFewer lines of code<br />ReadFewer l...
The benefits of aspect-oriented programming<br />Improve Quality<br />Fewer lines of code	-> Fewer Defects<br />More autom...
The benefits of aspect-oriented programming<br />Decrease Maintenance Costs<br />Remember: <br />Fewer Defects<br />Mainte...
The benefits of aspect-oriented programming<br />Decrease Maintenance Costs<br />
Features<br />
Features<br />Code Transformation Primitives<br />Modifications<br />Introductions<br />Around Methods<br />Method Interce...
Features<br />Composite Aspects<br />Aspects composed of multiple primitive transformations<br />Advice = Additional Behav...
Features<br />Aspect Multicasting<br />Using a single line of code, apply an aspects to multiple elements of code based on...
Features<br />Attribute Inheritance<br />Interfaces<br />Classes<br />Virtual Methods<br />Assemblies (!)<br />- or -<br />
Robust Aspect Composition<br />Multiple aspects on the same element of code<br />Aspect dependency framework<br />Ordering...
Comparing Aspect Frameworks<br />Part 4<br />
Comparing Aspect Frameworks<br />Static vs Dynamic AOP<br />Spring.NET<br />Castle<br />MS Unity/PIAB<br />PostSharp<br />...
Comparing Aspect Frameworks<br />Expressiveness (1/2)<br />What can you do with the framework?<br />
Comparing Aspect Frameworks<br />Expressiveness (2/2)<br />How do you apply aspects to code?<br />
Comparing Aspect Frameworks<br />Non-Invasiveness<br />Can you use aspects without deep refactoring?<br />Require the use ...
Comparing Aspect Frameworks<br />Robustness<br />Can you prevent aspects from being improperly used?<br />
Comparing Aspect Frameworks<br />Misc.<br />Other points that matter<br />
http://www.sharpcrafters.com/geersch@gmail.com<br />
Upcoming SlideShare
Loading in …5
×

Post sharp presentation

752 views

Published on

0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
752
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
22
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Post sharp presentation

  1. 1. An Introduction to Aspect-Oriented Programming in Microsoft .NET.<br />Produce Cleaner Code with Aspect-Oriented Programming<br />Christophe Geers<br />geersch@gmail.com<br />http://www.cgeers.com/<br />
  2. 2. AOP Facts<br />
  3. 3. Agenda<br />The Problem with Conventional Programming<br />What is AOP?<br />Why AOP?<br />PostSharp Features<br />Comparing AOP Frameworks<br />
  4. 4. The Problem with Conventional Programming<br />Part 1<br />
  5. 5. In the beginning there was nothing.<br />public class RentalService<br />{<br />}<br />
  6. 6. Customer said: let there be business value.<br />publicclassRentalService<br />{<br />publicvoid RentMovie(Guid movieId, Guid customerId)<br /> {<br />Moviemovie = Movie.GetById(movieId);<br />Customercustomer = Customer.GetById(customerId);<br /> <br />var history = newRentalHistory();<br /> history.MovieId = movieId;<br /> history.CustomerId = customerId;<br /> history.RentedOn = DateTime.Now;<br />customer.History.Add(history);<br /> <br /> customer.Balance -= movie.RentalPrice;<br />}<br />}<br />And there was business code.<br />
  7. 7. publicclassRentalService<br />{<br />privatestaticreadonlyTraceSource Trace =<br />newTraceSource(typeof (RentalService).FullName);<br /> <br />publicvoid RentMovie(Guid movieId, Guid customerId)<br /> {<br /> Trace.TraceInformation(<br />"Entering RentalService.RentMovie(movieId = {0},_customerId = {1})",<br /> movieId, customerId);<br /> <br />try<br /> { <br />Movie movie = Movie.GetById(movieId);<br />Customer customer = Customer.GetById(customerId);<br /> <br />var history = newRentalHistory();<br /> history.MovieId = movieId;<br /> history.CustomerId = customerId;<br /> history.RentedOn = DateTime.Now;<br /> customer.History.Add(history);<br /> <br /> customer.Balance -= movie.RentalPrice;<br /> <br /> Trace.TraceInformation(<br />"Leaving RentalService.RentMovie(movieId = {0}, customerId = {1})",<br /> movieId, customerId);<br /> }<br />catch (Exception ex)<br /> {<br />Trace.TraceEvent(TraceEventType.Error, 0,<br />"Exception: RentalService.RentMovie(movieId = {0}, customerId = {1}) <br /> failed: {2}",<br /> movieId, customerId, ex.Message);<br />throw;<br />}<br /> }<br />}<br /> <br />Testers said: Letthere be logging<br />And there was logging code.<br />
  8. 8. publicclassRentalService<br />{<br />privatestaticreadonlyTraceSource Trace =<br />newTraceSource(typeof (RentalService).FullName);<br /> <br />publicvoid RentMovie(Guid movieId, Guid customerId)<br /> {<br />if (movieId == Guid.Empty) thrownewArgumentException("movieId");<br />if (customerId == Guid.Empty) thrownewArgumentException("customerId");<br /> <br /> Trace.TraceInformation(<br />"Entering RentalService.RentMovie(movieId = {0},_customerId = {1})",<br /> movieId, customerId);<br /> <br />try<br /> {<br /> <br />Moviemovie = Movie.GetById(movieId);<br />Customercustomer = Customer.GetById(customerId);<br /> <br />var history = newRentalHistory();<br /> history.MovieId = movieId;<br /> history.CustomerId = customerId;<br /> history.RentedOn = DateTime.Now;<br /> customer.History.Add(history);<br /> <br /> customer.Balance -= movie.RentalPrice;<br /> <br /> Trace.TraceInformation(<br />"Leaving RentalService.RentMovie(movieId = {0}, customerId = {1})",<br /> movieId, customerId);<br /> }<br />catch (Exception ex)<br /> {<br />Trace.TraceEvent(TraceEventType.Error, 0,<br />"Exception: RentalService.RentMovie(movieId = {0}, customerId = {1}) <br />failed : {2}", movieId, customerId, ex.Message);<br />throw;<br /> }<br /> }<br />}<br /> <br />Devssaid: Letthere be defensive programming<br />Thenthere was precondition checking code.<br />
  9. 9. publicclassRentalService<br />{<br />privatestaticreadonlyTraceSource Trace =<br />newTraceSource(typeof (RentalService).FullName);<br /> <br />publicvoid RentMovie(Guid movieId, Guid customerId)<br /> {<br />if (movieId == Guid.Empty) thrownewArgumentException("movieId");<br />if (customerId == Guid.Empty) thrownew<br /> ArgumentException("customerId");<br /> <br /> Trace.TraceInformation(<br />"Entering RentalService.RentMovie(movieId = {0},_customerId = <br /> {1})“, movieId, customerId); <br />try<br />{<br />using (var scope = newTransactionScope())<br />{<br />Moviemovie = Movie.GetById(movieId);<br />Customercustomer = Customer.GetById(customerId);<br /> <br />var history = newRentalHistory();<br /> history.MovieId = movieId;<br /> history.CustomerId = customerId;<br /> history.RentedOn = DateTime.Now;<br /> customer.History.Add(history);<br /> <br /> customer.Balance -= movie.RentalPrice;<br /> <br />ContextManager.Context.SaveChanges();<br /> scope.Complete();<br /> <br /> Trace.TraceInformation(<br />"Leaving RentalService.RentMovie(movieId = {0}, customerId <br /> = {1})“, movieId, customerId);<br /> }<br /> }<br />catch (Exception ex)<br /> {<br />Trace.TraceEvent(TraceEventType.Error, 0,<br />"Exception: RentalService.RentMovie(movieId = {0}, customerId = <br /> {1}) failed : {2}", movieId, customerId, ex.Message);<br />throw;<br /> }<br /> }<br />}<br /> <br />Let there be transactions.<br />And there was transaction handling code.<br />
  10. 10. publicclassRentalService<br />{<br />privatestaticreadonlyTraceSource Trace =<br />newTraceSource(typeof (RentalService).FullName);<br /> <br />publicvoid RentMovie(Guid movieId, Guid customerId)<br /> {<br />if (movieId == Guid.Empty) thrownewArgumentException("movieId");<br />if (customerId == Guid.Empty) thrownew<br /> ArgumentException("customerId");<br /> <br />try<br /> {<br /> Trace.TraceInformation(<br />"Entering RentalService.RentMovie(movieId = {0},_customerId = <br /> {1})“, movieId, customerId); <br />try<br /> {<br />using (var scope = newTransactionScope())<br /> {<br />Moviemovie = Movie.GetById(movieId);<br />Customercustomer = Customer.GetById(customerId);<br /> <br />var history = newRentalHistory();<br /> history.MovieId = movieId;<br /> history.CustomerId = customerId;<br /> history.RentedOn = DateTime.Now;<br /> customer.History.Add(history);<br /> <br /> customer.Balance -= movie.RentalPrice;<br /> <br />ContextManager.Context.SaveChanges();<br /> scope.Complete();<br /> <br /> Trace.TraceInformation(<br />"Leaving RentalService.RentMovie(movieId = {0}, <br /> customerId = {1})“, movieId, customerId);<br /> }<br /> }<br />catch (Exception ex)<br /> {<br />Trace.TraceEvent(TraceEventType.Error, 0,<br />"Exception: RentalService.RentMovie(movieId = {0}, customerId = <br /> {1}) failed : {2}", movieId, customerId, ex.Message);<br />throw;<br /> }<br /> }<br />catch (Exception ex)<br /> {<br />if (ExceptionManager.Handle(ex)) throw;<br />}<br /> }<br />}<br /> <br /> <br />Let there be user-friendly error messages.<br />And there was exception handling code.<br />
  11. 11. We want a nice separation of concerns (assembly > namespace > class > method)<br />OOP forces us to write crap!<br />Code Scattering<br />Code Tangling<br />Code Coupling<br />Layer 1<br />Layer 2<br />Why do we write ugly code?<br />
  12. 12. Security<br />Exception Handling<br />Tracing<br />Monitoring<br />Transaction<br />Data Binding<br />Thread Sync<br />Caching<br />Validation<br />Non-Functional Requirements<br />Cross-Cutting Concerns<br />
  13. 13. Encapsulating Infrastructure Concerns?<br />
  14. 14. Aspects!<br />
  15. 15. Strengthen Applications With Aspects<br />Show Me!<br />
  16. 16. Show Me!<br />1. Add a reference to PostSharp.dll<br />
  17. 17. Show Me!<br />2. Write an aspect {Demo}<br />
  18. 18. Show Me!<br />3. Apply the aspect {Demo}<br />
  19. 19. Show Me!<br />How does it work?<br />1. Source<br />2. Compiler<br />3. PostSharp<br />4. Run Time<br />
  20. 20. The Idea Behind AOP<br />Part 2<br />
  21. 21. Problem Domain<br />Cross-Cutting Concerns<br />Solution Domain<br />Separation of Concerns<br />
  22. 22. What is AOP?<br />An extension of (not an alternative to) OOP that addresses the issue of cross-cutting concerns by providing a mean to:<br />Encapsulate cross-cutting concerns into Aspects = collection of transformations of code<br />Applyaspects to elements of code<br />
  23. 23. 15 Years of AOP History<br />Hype Years<br />Productivity Years<br />Research Years<br />
  24. 24. Why You Should Care<br />The benefits of aspect-oriented programming<br />
  25. 25. The benefits of aspect-oriented programming<br />Decrease Development Costs<br />WriteFewer lines of code<br />ReadFewer lines of code <br />Concise, clear, understandable code<br />Size-Cost relationship is superlinear<br />
  26. 26. The benefits of aspect-oriented programming<br />Improve Quality<br />Fewer lines of code -> Fewer Defects<br />More automation -> Fewer Defects<br />Less boiler-plate code -> More interesting work -> Increased attention -> Fewer Defects<br />
  27. 27. The benefits of aspect-oriented programming<br />Decrease Maintenance Costs<br />Remember: <br />Fewer Defects<br />Maintenance = 75% Reading Code<br />How do you change a pattern once it’s implemented?<br />Better architecture metrics:<br />Decreased component coupling<br />Increased component cohesion<br />
  28. 28. The benefits of aspect-oriented programming<br />Decrease Maintenance Costs<br />
  29. 29. Features<br />
  30. 30. Features<br />Code Transformation Primitives<br />Modifications<br />Introductions<br />Around Methods<br />Method Interception<br />Property Interception<br />Field Interception<br />Event Interception<br />Interface Introduction<br />Method Introduction<br />Property Introduction<br />Event Introduction<br />Member Import<br />Custom Attribute Intro<br />Managed Resource Intro<br />
  31. 31. Features<br />Composite Aspects<br />Aspects composed of multiple primitive transformations<br />Advice = Additional Behavior ≈ Transformation<br />Pointcut = Expression selecting target elements of code<br />Declarative<br />LINQ over System.Reflection<br />Adding aspects dynamically: IAspectProvider<br />
  32. 32. Features<br />Aspect Multicasting<br />Using a single line of code, apply an aspects to multiple elements of code based on:<br />Attributes (public/private, virtual/sealed, …)<br />Naming conventions<br />
  33. 33. Features<br />Attribute Inheritance<br />Interfaces<br />Classes<br />Virtual Methods<br />Assemblies (!)<br />- or -<br />
  34. 34. Robust Aspect Composition<br />Multiple aspects on the same element of code<br />Aspect dependency framework<br />Ordering<br />Requirement<br />Conflict<br />Strong ordering and commutativity<br /> Deterministic Behavior<br />D<br />C<br />B<br />A<br />
  35. 35. Comparing Aspect Frameworks<br />Part 4<br />
  36. 36. Comparing Aspect Frameworks<br />Static vs Dynamic AOP<br />Spring.NET<br />Castle<br />MS Unity/PIAB<br />PostSharp<br />LinFu<br />Build-Time:<br />Very Expressive<br />Robust Model<br />Not InvasiveStatic<br />Run-Time:Less ExpressiveBrittle Model<br />InvasiveDynamic<br />Hybrid<br />
  37. 37. Comparing Aspect Frameworks<br />Expressiveness (1/2)<br />What can you do with the framework?<br />
  38. 38. Comparing Aspect Frameworks<br />Expressiveness (2/2)<br />How do you apply aspects to code?<br />
  39. 39. Comparing Aspect Frameworks<br />Non-Invasiveness<br />Can you use aspects without deep refactoring?<br />Require the use of factory methods<br />
  40. 40. Comparing Aspect Frameworks<br />Robustness<br />Can you prevent aspects from being improperly used?<br />
  41. 41. Comparing Aspect Frameworks<br />Misc.<br />Other points that matter<br />
  42. 42. http://www.sharpcrafters.com/geersch@gmail.com<br />

×