This document introduces aspect-oriented programming (AOP) and how it can be used to separate cross-cutting concerns from core business logic. It discusses how AOP frameworks like PostSharp allow aspects to modularize features like logging, transactions, and security. The document provides an example of how a rental booking method grows over time to include these concerns. It compares different AOP frameworks and concludes that PostSharp allows building aspects with strong robustness while minimizing code invasiveness.
Introduction to Aspect-Oriented Programming with PostSharp
1. An Introduction to Aspect-Oriented Programming in Microsoft .NET. Produce Cleaner Code with Aspect-Oriented Programming Gaël Fraiteur gael@sharpcrafters.comhttp://www.sharpcrafters.com/
6. In the beginning there was nothing. publicclassCustomerProcesses { }
7. Customer said: let there be business value. publicclassCustomerProcesses { publicvoid RentBook( int bookId, int customerId ) { Book book = Book.GetById( bookId ); Customer customer = Customer.GetById( customerId ); book.RentedTo = customer; customer.AccountLines.Add(string.Format( "Rental of book {0}.", book ), book.RentalPrice ); customer.Balance -= book.RentalPrice; } } And there was business code.
8. internalclassCustomerProcesses { privatestaticreadonlyTraceSource trace = newTraceSource( typeof (CustomerProcesses).FullName ); publicvoid RentBook( int bookId, int customerId ) { trace.TraceInformation( "Entering CustomerProcesses.CreateCustomer( bookId = {0}, customerId = {1} )", bookId, customerId ); try{ Book book = Book.GetById( bookId ); Customer customer = Customer.GetById( customerId ); book.RentedTo = customer; customer.AccountLines.Add( string.Format( "Rental of book {0}.", book ), book.RentalPrice ); customer.Balance -= book.RentalPrice; trace.TraceInformation( "Leaving CustomerProcesses.CreateCustomer( bookId = {0}, customerId = {1} )", bookId, customerId ); } catch ( Exception e ) { trace.TraceEvent( TraceEventType.Error, 0, "Exception: CustomerProcesses.CreateCustomer( bookId = {0}, customerId = {1} ) failed : {2}", bookId, customerId, e.Message ); throw; } } } Testers said: Letthere be logging And there was logging code.
13. We want a nice separation of concerns (assembly > namespace > class > method) OOP forces us to write crap! Code Scattering Code Tangling Code Coupling Layer 1 Layer 2 Why do we write ugly code?
25. What is AOP? An extension of (not an alternative to) OOP that addresses the issue of cross-cutting concerns by providing a mean to: Encapsulate cross-cutting concerns into Aspects = collection of transformations of code Applyaspects to elements of code
26. 15 Years of AOP History Hype Years Productivity Years Research Years
27. Why You Should Care The benefits of aspect-oriented programming
28. The benefits of aspect-oriented programming Decrease Development Costs WriteFewer lines of code ReadFewer lines of code Concise, clear, understandable code Size-Cost relationship is superlinear
29. The benefits of aspect-oriented programming Improve Quality Fewer lines of code -> Fewer Defects More automation -> Fewer Defects Less boiler-plate code -> More interesting work -> Increased attention -> Fewer Defects
30. The benefits of aspect-oriented programming Decrease Maintenance Costs Remember: Fewer Defects Maintenance = 75% Reading Code How do you change a pattern once it’s implemented? Better architecture metrics: Decreased component coupling Increased component cohesion
31. The benefits of aspect-oriented programming Decrease Maintenance Costs
34. Features Code Transformation Primitives Modifications Introductions Around Methods Method Interception Property Interception Field Interception Event Interception Interface Introduction Method Introduction Property Introduction Event Introduction Member Import Custom Attribute Intro Managed Resource Intro
35. Features Composite Aspects Aspects composed of multiple primitive transformations Advice = Additional Behavior ≈ Transformation Pointcut = Expression selecting target elements of code Declarative LINQ over System.Reflection Adding aspects dynamically: IAspectProvider
36. Features Aspect Multicasting Using a single line of code, apply an aspects to multiple elements of code based on: Attributes (public/private, virtual/sealed, …) Naming conventions
38. Robust Aspect Composition Multiple aspects on the same element of code Aspect dependency framework Ordering Requirement Conflict Strong ordering and commutativity Deterministic Behavior D C B A
39. Visual Studio Extension 1. Code Adornment + Clickable Tooltips “What aspects are applied to a given element of code?” 1. Adornment + Tooltip Aspects Base Code Bi-Directional Navigation 2. Aspect Browser “Which elements of code is a given a given aspect applied to?” 2. Aspect Browser
43. AO Infrastructure Transparent Proxies Enhanced Object Consumer Object Transparent Proxy RealProxy Aspects The transparent proxy is type-compatible with the enhanced object(CLR-provided magic)
44. JIT-Emitted Proxy AO Infrastructure Consumer Object Proxy Enhanced Object Aspects The proxy implements an interface of the enhanced object.
45. JIT-Emitted Subclass AO Infrastructure Consumer Object Proxy Enhanced Object Aspects The proxy extends (inherits from) the enhanced object.
46. Comparing Aspect Frameworks Static vs Dynamic AOP Spring.NET Castle MS Unity/PIAB PostSharp LinFu Build-Time: Very Expressive Robust Model Not InvasiveStatic Run-Time:Less ExpressiveBrittle Model InvasiveDynamic Hybrid
52. Comparing Aspect Frameworks My Own Summary Aspects on Service Boundaries: use your favorite application framework. Aspects on Ordinary and GUI Objects: use PostSharp. You can mix PostSharp with your favorite application framework!