Your SlideShare is downloading. ×
0
An Introduction to Aspect-Oriented Programming in Microsoft .NET.<br />Produce Cleaner Code with Aspect-Oriented Programmi...
AOP Facts<br />
Featured PostSharp Customers<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 />publicclassCustomerProcesses<br />{<br />}<br />
Customer said: let there be business value.<br />publicclassCustomerProcesses<br />{<br />publicvoid RentBook( int bookId,...
internalclassCustomerProcesses<br />{<br />privatestaticreadonlyTraceSource trace =<br />newTraceSource( typeof (CustomerP...
internalclassCustomerProcesses<br />{<br />privatestaticreadonlyTraceSource trace =<br />newTraceSource(typeof(CustomerPro...
internalclassCustomerProcesses<br />{<br />privatestaticreadonlyTraceSource trace =<br />newTraceSource(typeof(CustomerPro...
internalclassCustomerProcesses<br />{<br />privatestaticreadonlyTraceSource trace =<br />newTraceSource(typeof(CustomerPro...
AKSEL BACHMEIER architect<br />YOHJI YAMAMOTOcustomer<br />
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...
We have patterns. How to implement them?<br />Template-Based Code Generators<br />Anonymous Methods (Functional Programmin...
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<br />
Show Me!<br />3. Apply the aspect<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 3<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 />
The benefits of aspect-oriented programming<br />Optimize Skillsets<br />I understand provisioning processes better than a...
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...
Visual Studio Extension<br />1. Code Adornment + Clickable Tooltips<br />“What aspects are applied to a given element of c...
Comparing Aspect Frameworks<br />Part 4<br />
Comparing Aspect Frameworks<br />What to compare?<br />Expressive<br />Non-Invasive<br />Supported<br />Framework<br />Rob...
Build-Time MSIL Transformation<br />Consumer Object<br />Enhanced Object<br />Aspects<br />
AO Infrastructure<br />Transparent Proxies<br />Enhanced Object<br />Consumer Object<br />Transparent Proxy<br />RealProxy...
JIT-Emitted Proxy<br />AO Infrastructure<br />Consumer Object<br />Proxy<br />Enhanced Object<br />Aspects<br />The proxy ...
JIT-Emitted Subclass<br />AO Infrastructure<br />Consumer Object<br />Proxy<br />Enhanced Object<br />Aspects<br />The pro...
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 />
Comparing Aspect Frameworks<br />My Own Summary<br />Aspects on Service Boundaries: use your favorite application framewor...
Summary<br />
We need Aspects!<br />
We have great frameworks!<br />and PostSharp happens to be the best in .NET :).<br />
http://www.sharpcrafters.com/gael@sharpcrafters.com<br />
Upcoming SlideShare
Loading in...5
×

Produce Cleaner Code with Aspect-Oriented Programming

2,436

Published on

Rather than giving us a nice separation of concerns (assembly > namespace > class > method), there are times when OOP forces us to duplicate boilerplate code, resulting in code scattering, tangling and coupling.

Gael Fraiteur, SharpCrafters Founder and Principal Engineer, speaks about the problem with conventional programming, give a gentle introduction to AOP, show how it works, and why you should be using it to eliminate boilerplate code from your life.

Published in: Technology
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
2,436
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
79
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Transcript of "Produce Cleaner Code with Aspect-Oriented Programming"

  1. 1. An Introduction to Aspect-Oriented Programming in Microsoft .NET.<br />Produce Cleaner Code with Aspect-Oriented Programming<br />Gaël Fraiteur<br />gael@sharpcrafters.comhttp://www.sharpcrafters.com/<br />
  2. 2. AOP Facts<br />
  3. 3. Featured PostSharp Customers<br />
  4. 4. Agenda<br />The Problem with Conventional Programming<br />What is AOP?<br />Why AOP?<br />PostSharp Features<br />Comparing AOP Frameworks<br />
  5. 5. The Problem with Conventional Programming<br />Part 1<br />
  6. 6. In the beginning there was nothing.<br />publicclassCustomerProcesses<br />{<br />}<br />
  7. 7. Customer said: let there be business value.<br />publicclassCustomerProcesses<br />{<br />publicvoid RentBook( int bookId, int customerId )<br /> {<br />Book book = Book.GetById( bookId );<br />Customer customer = Customer.GetById( customerId );<br /> <br /> book.RentedTo = customer;<br /> customer.AccountLines.Add(string.Format( "Rental of book {0}.", book ), book.RentalPrice );<br /> customer.Balance -= book.RentalPrice;<br /> }<br />}<br />And there was business code.<br />
  8. 8. internalclassCustomerProcesses<br />{<br />privatestaticreadonlyTraceSource trace =<br />newTraceSource( typeof (CustomerProcesses).FullName );<br /> <br />publicvoid RentBook( int bookId, int customerId )<br /> {<br /> trace.TraceInformation(<br />"Entering CustomerProcesses.CreateCustomer( bookId = {0}, customerId = {1} )",<br /> bookId, customerId ); try{ <br /> Book book = Book.GetById( bookId );<br />Customer customer = Customer.GetById( customerId );<br /> <br /> book.RentedTo = customer;<br /> customer.AccountLines.Add( string.Format( "Rental of book {0}.", book ), book.RentalPrice );<br /> customer.Balance -= book.RentalPrice;<br /> trace.TraceInformation(<br /> "Leaving CustomerProcesses.CreateCustomer( bookId = {0}, customerId = {1} )",<br /> bookId, customerId );<br /> }<br /> catch ( Exception e )<br /> {<br /> trace.TraceEvent( TraceEventType.Error, 0,<br /> "Exception: CustomerProcesses.CreateCustomer( bookId = {0}, customerId = {1} ) failed : {2}",<br /> bookId, customerId, e.Message );<br /> throw;<br /> }  <br /> }<br />}<br />Testers said: Letthere be logging<br />And there was logging code.<br />
  9. 9. internalclassCustomerProcesses<br />{<br />privatestaticreadonlyTraceSource trace =<br />newTraceSource(typeof(CustomerProcesses).FullName);<br /> <br />publicvoid RentBook(int bookId, int customerId)<br /> {<br />if (bookId <= 0) thrownewArgumentOutOfRangeException("bookId");<br />if (customerId <= 0) thrownewArgumentOutOfRangeException("customerId");<br /> <br /> trace.TraceInformation(<br />"Entering CustomerProcesses.CreateCustomer( bookId = {0}, customerId = {1} )",<br /> bookId, customerId);<br /> <br />try<br /> {<br />Book book = Book.GetById(bookId);<br />Customer customer = Customer.GetById(customerId);<br /> <br /> book.RentedTo = customer;<br /> customer.AccountLines.Add(string.Format("Rental of book {0}.", book), book.RentalPrice);<br /> customer.Balance -= book.RentalPrice;<br /> <br /> trace.TraceInformation(<br />"Leaving CustomerProcesses.CreateCustomer( bookId = {0}, customerId = {1} )“, bookId, customerId);<br /> }<br />catch (Exception e)<br /> {<br /> trace.TraceEvent(TraceEventType.Error, 0,<br /> "Exception: CustomerProcesses.CreateCustomer( bookId = {0}, customerId = {1} ) failed : {2}",<br /> bookId, customerId, e.Message);<br />throw;<br /> }<br /> }<br />}<br />Devssaid: Letthere be defensive programming<br />Thenthere was precondition checking code.<br />
  10. 10. internalclassCustomerProcesses<br />{<br />privatestaticreadonlyTraceSource trace =<br />newTraceSource(typeof(CustomerProcesses).FullName);<br /> <br />publicvoid RentBook(int bookId, int customerId)<br /> {<br />if (bookId <= 0) thrownewArgumentOutOfRangeException("bookId");<br />if (customerId <= 0) thrownewArgumentOutOfRangeException("customerId");<br /> <br /> trace.TraceInformation(<br />"Entering CustomerProcesses.CreateCustomer( bookId = {0}, customerId = {1} )“, bookId, customerId);<br /> <br />try<br /> {<br />for (int i = 0; ; i++)<br /> {<br />try<br /> {<br />using (var ts = newTransactionScope())<br /> {<br />Book book = Book.GetById(bookId);<br />Customer customer = Customer.GetById(customerId);<br /> <br /> book.RentedTo = customer;<br /> customer.AccountLines.Add(string.Format("Rental of book {0}.", book), book.RentalPrice);<br /> customer.Balance -= book.RentalPrice;<br /> <br /> ts.Complete();<br /> }<br /> <br />break;<br /> }<br />catch (TransactionConflictException)<br /> {<br />if (i < 3)<br />continue;<br />else<br />throw;<br /> }<br /> }<br /> <br /> trace.TraceInformation(<br />"Leaving CustomerProcesses.CreateCustomer( bookId = {0}, customerId = {1} )",<br /> bookId, customerId);<br /> }<br />catch (Exception e)<br /> {<br /> trace.TraceEvent(TraceEventType.Error, 0,<br />"Exception: CustomerProcesses.CreateCustomer( bookId = {0}, customerId = {1} ) failed : {2}",<br /> bookId, customerId, e.Message);<br />throw;<br /> }<br /> }<br />}<br />Let there be safe concurrent execution.<br />And there was transaction handling code.<br />
  11. 11. internalclassCustomerProcesses<br />{<br />privatestaticreadonlyTraceSource trace =<br />newTraceSource(typeof(CustomerProcesses).FullName);<br /> <br />publicvoid RentBook(int bookId, int customerId)<br /> {<br />if (bookId <= 0) thrownewArgumentOutOfRangeException("bookId");<br />if (customerId <= 0) thrownewArgumentOutOfRangeException("customerId");<br /> <br />try<br /> {<br /> trace.TraceInformation(<br />"Entering CustomerProcesses.CreateCustomer( bookId = {0}, customerId = {1} )",<br /> bookId, customerId );<br /> <br />try<br /> {<br />for ( int i = 0;; i++ )<br /> {<br />try<br /> {<br />using ( var ts = newTransactionScope() )<br /> {<br />Book book = Book.GetById( bookId );<br />Customer customer = Customer.GetById( customerId );<br /> <br /> book.RentedTo = customer;<br /> customer.AccountLines.Add( string.Format( "Rental of book {0}.", book ), book.RentalPrice );<br /> customer.Balance -= book.RentalPrice;<br /> <br /> ts.Complete();<br /> }<br /> <br />break;<br /> }<br />catch ( TransactionConflictException )<br /> {<br />if ( i < 3 )<br />continue;<br />else<br />throw;<br /> }<br /> }<br /> <br /> trace.TraceInformation(<br />"Leaving CustomerProcesses.CreateCustomer( bookId = {0}, customerId = {1} )",<br /> bookId, customerId );<br /> }<br />catch ( Exception e )<br /> {<br /> trace.TraceEvent( TraceEventType.Error, 0,<br />"Exception: CustomerProcesses.CreateCustomer( bookId = {0}, customerId = {1} ) failed : {2}",<br /> bookId, customerId, e.Message );<br />throw;<br /> }<br /> }<br />catch ( Exception e )<br /> {<br />if (ExceptionManager.Handle(e)) throw;<br /> }<br /> }<br />}<br />Let there be user-friendly error messages.<br />And there was exception handling code.<br />
  12. 12. AKSEL BACHMEIER architect<br />YOHJI YAMAMOTOcustomer<br />
  13. 13. 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 />
  14. 14. 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 />
  15. 15. We have patterns. How to implement them?<br />Template-Based Code Generators<br />Anonymous Methods (Functional Programming)<br />Object-Oriented Alternatives<br />
  16. 16. Encapsulating Infrastructure Concerns?<br />
  17. 17. Aspects!<br />
  18. 18. Strengthen Applications With Aspects<br />Show Me!<br />
  19. 19. Show Me!<br />1. Add a reference to PostSharp.dll<br />
  20. 20. Show Me!<br />2. Write an aspect<br />
  21. 21. Show Me!<br />3. Apply the aspect<br />
  22. 22. Show Me!<br />How does it work?<br />1. Source<br />2. Compiler<br />3. PostSharp<br />4. Run Time<br />
  23. 23. The Idea Behind AOP<br />Part 3<br />
  24. 24. Problem Domain<br />Cross-Cutting Concerns<br />Solution Domain<br />Separation of Concerns<br />
  25. 25. 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 />
  26. 26. 15 Years of AOP History<br />Hype Years<br />Productivity Years<br />Research Years<br />
  27. 27. Why You Should Care<br />The benefits of aspect-oriented programming<br />
  28. 28. 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 />
  29. 29. 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 />
  30. 30. 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 />
  31. 31. The benefits of aspect-oriented programming<br />Decrease Maintenance Costs<br />
  32. 32. The benefits of aspect-oriented programming<br />Optimize Skillsets<br />I understand provisioning processes better than anyone in this company,<br />I master multithreading better than anyone on earth<br />Picture © Darren Rogers and chatwoodsfp (Flicker)<br />
  33. 33. Features<br />
  34. 34. 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 />
  35. 35. 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 />
  36. 36. 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 />
  37. 37. Features<br />Attribute Inheritance<br />Interfaces<br />Classes<br />Virtual Methods<br />Assemblies (!)<br />- or -<br />
  38. 38. 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 />
  39. 39. Visual Studio Extension<br />1. Code Adornment + Clickable Tooltips<br />“What aspects are applied to a given element of code?”<br />1. Adornment + Tooltip<br />Aspects<br />Base Code<br />Bi-Directional Navigation<br />2. Aspect Browser<br />“Which elements of code is a given a given aspect applied to?”<br />2. Aspect Browser<br />
  40. 40. Comparing Aspect Frameworks<br />Part 4<br />
  41. 41. Comparing Aspect Frameworks<br />What to compare?<br />Expressive<br />Non-Invasive<br />Supported<br />Framework<br />Robust<br />Productive<br />Dynamic<br />
  42. 42. Build-Time MSIL Transformation<br />Consumer Object<br />Enhanced Object<br />Aspects<br />
  43. 43. AO Infrastructure<br />Transparent Proxies<br />Enhanced Object<br />Consumer Object<br />Transparent Proxy<br />RealProxy<br />Aspects<br />The transparent proxy is type-compatible with the enhanced object(CLR-provided magic)<br />
  44. 44. JIT-Emitted Proxy<br />AO Infrastructure<br />Consumer Object<br />Proxy<br />Enhanced Object<br />Aspects<br />The proxy implements an interface of the enhanced object.<br />
  45. 45. JIT-Emitted Subclass<br />AO Infrastructure<br />Consumer Object<br />Proxy<br />Enhanced Object<br />Aspects<br />The proxy extends (inherits from) the enhanced object.<br />
  46. 46. 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 />
  47. 47. Comparing Aspect Frameworks<br />Expressiveness (1/2)<br />What can you do with the framework?<br />
  48. 48. Comparing Aspect Frameworks<br />Expressiveness (2/2)<br />How do you apply aspects to code?<br />
  49. 49. Comparing Aspect Frameworks<br />Non-Invasiveness<br />Can you use aspects without deep refactoring?<br />Require the use of factory methods<br />
  50. 50. Comparing Aspect Frameworks<br />Robustness<br />Can you prevent aspects from being improperly used?<br />
  51. 51. Comparing Aspect Frameworks<br />Misc.<br />Other points that matter<br />
  52. 52. Comparing Aspect Frameworks<br />My Own Summary<br />Aspects on Service Boundaries: use your favorite application framework.<br />Aspects on Ordinary and GUI Objects: use PostSharp.<br />You can mix PostSharp with your favorite application framework!<br />
  53. 53. Summary<br />
  54. 54. We need Aspects!<br />
  55. 55. We have great frameworks!<br />and PostSharp happens to be the best in .NET :).<br />
  56. 56. http://www.sharpcrafters.com/gael@sharpcrafters.com<br />
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×