Chapter 1. Introducing AOP
Listing 1.1. A simple program that calls service methods in sequence
Listing 1.2. Example of refactoring using DI instead of AOP
Listing 1.3. Use of the decorator pattern in pseudocode
Listing 1.4. Using AOP instead of DI for cross-cutting concerns
Listing 1.5. Pseudocode example of an extremely simple AddressBookService
Listing 1.6. Pseudocode example with argument checking split out using AOP
Chapter 2. Acme Car Rental
Listing 2.1. An implementation of the accrual service
Listing 2.2. A simple Console application to test the business logic
Listing 2.3. Accrue code, now with logging
Listing 2.4. Redeem code, now with logging
Listing 2.5. Accrue with defensive programming
Listing 2.6. Redeem with defensive programming
Listing 2.7. Accrue with a transaction
Listing 2.8. Redeem with a transaction
Listing 2.9. Accrue with transaction and retries
Listing 2.10. Redeem with transaction and retries
Listing 2.11. Accrue with exception handling
Listing 2.12. Redeem with exception handling
Listing 2.13. Redemption service refactored with DI
Listing 2.14. Accrual service refactored with DI
Listing 2.15. Combined exception handler and transaction handler
Listing 2.16. An aggregate service for orchestrating two services
Listing 2.17. Accrue method’s defensive programming and logging
Listing 2.18. A method boundary aspect to handle logging
Listing 2.19. Applying the logging aspect to the Accrue and Redeem methods
Listing 2.20. Examining and logging argument value
Listing 2.21. An alternative way to log certain entities
Listing 2.22. A defensive programming aspect
Listing 2.23. Refactoring to aspects with an attribute
Listing 2.24. A transaction aspect
Listing 2.25. Continuing to refactor with aspects
Listing 2.26. An aspect to handle exceptions
Listing 2.27. All cross-cutting concerns refactored into aspects
Chapter 3. Call this instead: intercepting methods
Listing 3.1. Calling Send method on TwitterClient service class
Listing 3.2. Indicating which method to intercept with an attribute
Listing 3.3. Calling the Send method on the TwitterClient service class
Listing 3.4. Adding code to the interceptor
Listing 3.5. Three different transaction scenarios
Listing 3.6. A Main method to try out the Save scenarios
Listing 3.7. Basic transaction interceptor, used with proxy generator
Listing 3.8. Using ProxyGenerator to apply the TransactionWithRetries aspect
Listing 3.9. Using Dispose to rollback
Listing 3.10. Adding a loop to retry
Listing 3.11. Transaction with maximum retries specified in constructor
Listing 3.12. Full Form1 class with button click event handler
Listing 3.13. Checking whether Invoke is necessary
Listing 3.14. Wouldn’t it be nice if threading were more like this?
Listing 3.15. UIThread interceptor aspect
Chapter 4. Before and after: boundary aspects
Listing 4.1. Calling a GetBattingAverage method on a service class
Listing 4.2. Using an attribute to indicate which method to bound
Listing 4.3. Using a class member for shared state
Listing 4.4. A Console application showing the pitfalls of using an aspect field in PostSharp
Listing 4.5. Using MethodExecutionTag to share state
Listing 4.6. A boundary aspect that overrides only OnExit
Listing 4.7. An equivalent interception aspect
Listing 4.8. Configuring MyHttpModule in Web.config
Listing 4.9. Event handlers in MyHttpModule
Listing 4.10. Writing text to the response at the beginning and end of a page
Listing 4.11. Subscribing to the BeginRequest boundary event
Listing 4.12. A class to detect mobile users
Listing 4.13. Detecting a mobile browser
Listing 4.14. Basic splash screen with two buttons
Listing 4.15. Handling the button clicks in code-behind
Listing 4.16. Adding checks to avoid redirect loops
Listing 4.17. Checking for a cookie
Listing 4.18. CarValue.aspx HTML and ASP.NET controls
Listing 4.19. Add items to each drop-down list
Listing 4.20. An event to handle a button click
Listing 4.21. Show the entire contents of Cache
Listing 4.22. Clicking the Get Value button
Listing 4.23. Storing the results of the method in a cache
Listing 4.24. Naïve GetCacheKey implementation
Listing 4.25. Add an OnEntry override to the CacheAspect class
Listing 4.26. Checking the cache in OnEntry
Listing 4.27. Refactored CarValueService to encapsulate options
Chapter 5. Get this instead: intercepting locations
Listing 5.1. Encapsulation of a private field with methods
Listing 5.2. The compiled program viewed through the ILSpy tool
Listing 5.3. Using a method interception aspect on a property
Listing 5.4. Using a PostSharp location interception aspect
Listing 5.5. Lazy loading with a property and a backing field
Listing 5.6. Thread-safe lazy loading with double-checked locking
Listing 5.7. Using System.Lazy<T>
Listing 5.8. Basic Console application with no lazy loading
Listing 5.9. A lazy-loading aspect
Listing 5.10. Lazy loading using Activator
Listing 5.11. SlowConstructor with a dependency on IMyService
Listing 5.13. Lazy loading with StructureMap
Listing 5.14. Using StructureMap in place of Activator
Listing 5.15. XAML to create textbox, button, and textblocks
Listing 5.16. A view model class representing the data
Listing 5.17. Binding a NameViewModel object to MainWindow’s DataContext
Listing 5.18. Binding controls to ViewModel properties
Listing 5.19. Implementing INotifyPropertyChanged on NameViewModel
Listing 5.20. Using CallerMemberName attribute
Listing 5.21. Boilerplate-free use of INotifyPropertyChanged
Listing 5.22. NameViewModel with a custom PostSharp aspect
Listing 5.23. Constructor that accepts derived property names
Listing 5.24. Perform all the steps of property notification in OnSetValue
Chapter 6. Unit testing aspects
Listing 6.1. Writing a test of the Reverse method
Listing 6.2. Testing for the presence of attributes
Listing 6.3. A static Log class
Listing 6.4. NUnit fixture to test MyInterceptor
Listing 6.6. MyOtherService service implementation and interface
Listing 6.7. LoggingService implementation and interface
Listing 6.8. MyLoggingAspect implementation
Listing 6.9. Testing MyLoggingAspect
Listing 6.10. MyService implementation and interface
Listing 6.11. Using MyService object in Main
Listing 6.12. Initializing and using StructureMap
Listing 6.13. One approach to using aspects with a complex domain
Listing 6.14. Using EnrichWith feature of StructureMap
Listing 6.15. More concise use of EnrichWith
Listing 6.17. A test of a PostSharp aspect
Listing 6.18. Program’s Main method
Listing 6.19. MyLoggingAspect with PostSharp
Listing 6.20. Dependency inversion via RuntimeInitialize
Listing 6.21. Creating an aspect object for the test
Listing 6.22. Call OnEntry and OnSuccess to execute the aspect
Listing 6.23. Verify that the logging operations happened
Listing 6.24. A class/method that reverses a string, and its unit test
Listing 6.25. Reverse method with aspect applied
Listing 6.26. Mocking ILoggingService to satisfy the aspect
Listing 6.27. Workaround with custom symbols
Listing 6.28. A global variable setting for unit testing
Listing 6.29. A thin aspect and the interface to which it’s delegating
Chapter 7. AOP implementation types
Listing 7.1. A Console program that uses a proxy generator
Listing 7.2. Creating an AssemblyBuilder and a ModuleBuilder
Listing 7.3. Define a Type and get a TypeBuilder
Listing 7.4. Define a field and get a FieldBuilder
Listing 7.5. Define a constructor and get an ILGenerator
Listing 7.6. Emitting CIL code for the constructor
Listing 7.7. Tweet method for the interface with an ILGenerator
Listing 7.8. Writing to Console and calling the real Tweet method with OpCodes
Chapter 8. Using AOP as an architectural tool
Listing 8.1. Logging the method that was called
Listing 8.2. Using Initialize to get the method name at compile time
Listing 8.3. A LocationInterceptionAspect to log usage of get
Listing 8.4. Using CompileTimeValidate to check the location name
Listing 8.5. Runtime checks on casting
Listing 8.6. Threading aspect of compile-time validation
Listing 8.7. Unsealable referential constraint
Listing 8.8. Unsealable demonstration
Listing 8.9. NHibernate ScalarConstraint
Listing 8.10. An NHibernate entity with a nonvirtual property
Listing 8.11. Excluding a member with AttributeExclude
Listing 8.12. AspectPriority for ordering
Listing 8.13. AttributeTargetElements to target only the instance constructor
Chapter 9. Aspect composition: example and execution
Listing 9.1. Multiple aspects on the same method
Listing 9.2. Specifying an aspect role
Listing 9.3. Specifying aspect role dependency
Listing 9.4. An aspect that requires another role
Listing 9.5. ProxyHelper from chapter 6
Listing 9.6. A demo class and two demo aspects
Listing 9.7. Use of multiple aspects on the same code in StructureMap
Listing 9.8. A StructureMap name-based convention for applying aspects
Listing 9.9. Added overloaded Proxify to ProxyHelper
Listing 9.10. Adding a convention to the assembly scanner
Listing 9.11. Using a namespace-based convention
Listing 9.12. Configure StructureMap with default conventions
Listing 9.13. Budget service, interface, and implementation
Listing 9.14. A static caching service
Listing 9.16. The main UI of the program
Listing 9.17. The main UI prepared for exception
Listing 9.18. Caching concern interface and constructor
Listing 9.19. OnEntry of the caching concern
Listing 9.20. Adapter interface to get method context
Listing 9.21. OnSuccess of the caching concern
Listing 9.22. Authorization concern interface and constructor
Listing 9.23. OnEntry of the authorization concern
Listing 9.24. PostSharp caching aspect
Listing 9.25. PostSharp method context adapter
Listing 9.26. PostSharp authorization aspect
Listing 9.27. Aspect composition of caching and authorization
Listing 9.28. DynamicProxy caching aspect Intercept code
Listing 9.29. Castle DynamicProxy method context adapter
Listing 9.30. Constructor and members of the Authorization interceptor
Listing 9.31. Authorization Intercept code
Listing 9.32. Another Proxify overload in ProxyHelper
Appendix A. Ecosystem of .NET AOP tools
Listing A.1. Simple LinFu example
Listing A.2. Modifying project file to add PostWeaveTask
Listing A.3. Simple SheepAspect example
Listing A.4. Simple MethodDecorator example
Listing A.5. A basic Castle Windsor and DynamicProxy example
Listing A.6. StructureMap interception
Listing A.7. Unity interception example