Log In
Or create an account -> 
Imperial Library
  • Home
  • About
  • News
  • Upload
  • Forum
  • Help
  • Login/SignUp

Index
AOP in .NET: Practical Aspect-Oriented Programming
Matthew D. Groves Copyright
Dedication
Brief Table of Contents Table of Contents Foreword Preface Acknowledgments About this Book
Roadmap Who should read this book? Code conventions and downloads Author Online About the author About the cover illustration
Part 1. Getting started with AOP Chapter 1. Introducing AOP
1.1. What is AOP?
1.1.1. Features
AOP’s purpose: Cross-cutting concerns An aspect’s job: The advice An aspect’s map: A pointcut Figure 1.1. A low-level flowchart of a program that uses a single service Figure 1.2. The same low-level flowchart with possible join points identified Listing 1.1. A simple program that calls service methods in sequence Figure 1.3. Flowchart representation—imagine exit join points after each step How AOP works: Weaving Figure 1.4. Tangling and scattering. In the printed volume, X represents red code and Y, the green code. Figure 1.5. Splitting up the classes and recombining them with weaving
1.1.2. Benefits
Clean up spaghetti code Reduce repetition 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 Encapsulation Listing 1.5. Pseudocode example of an extremely simple AddressBookService Listing 1.6. Pseudocode example with argument checking split out using AOP Listing 1.7. Encapsulated and reusable code
1.1.3. AOP in your daily life
Figure 1.6. The HttpModule lifecycle in relation to the request->ASP.NET page->response Figure 1.7. The ASP.NET MVC ActionFilter lifecycle
1.2. Hello, World
Figure 1.8. Starting NuGet with the UI Figure 1.9. Search for PostSharp and install with NuGet UI Figure 1.10. Console output of “Hello, world!” Figure 1.11. Output with MyAspect applied
1.3. Summary
Chapter 2. Acme Car Rental
2.1. Start a new project
Figure 2.1. Three-layer system architecture 2.1.1. Business requirements
Figure 2.2. Loyalty program rules
2.1.2. Necessary nonfunctional requirements
2.2. Life without AOP
Figure 2.3. Start new project 2.2.1. Write the business logic
Listing 2.1. An implementation of the accrual service
2.2.2. Testing the business logic
Listing 2.2. A simple Console application to test the business logic Figure 2.4. Console output simulating writes to the database
2.2.3. Add logging
Listing 2.3. Accrue code, now with logging Listing 2.4. Redeem code, now with logging
2.2.4. Introducing defensive programming
Listing 2.5. Accrue with defensive programming Listing 2.6. Redeem with defensive programming
2.2.5. Working with transactions and retries
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
2.2.6. Handling exceptions
Listing 2.11. Accrue with exception handling Listing 2.12. Redeem with exception handling
2.2.7. Refactor without AOP
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 The Facade Pattern Listing 2.16. An aggregate service for orchestrating two services
2.3. The cost of change
2.3.1. Requirements will change 2.3.2. Small versus large projects 2.3.3. Signature changes
Listing 2.17. Accrue method’s defensive programming and logging
2.3.4. Working on a team
2.4. Refactor with AOP
2.4.1. Start simple and isolate the 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
2.4.2. Refactor defensive programming
Listing 2.22. A defensive programming aspect Listing 2.23. Refactoring to aspects with an attribute
2.4.3. Creating an aspect for transactions and retries
Listing 2.24. A transaction aspect Listing 2.25. Continuing to refactor with aspects Figure 2.5. Console output with the use of AOP
2.4.4. Put exception handling into its own class
Listing 2.26. An aspect to handle exceptions Listing 2.27. All cross-cutting concerns refactored into aspects
2.5. Summary
Part 2. The Fundamentals of AOP Chapter 3. Call this instead: intercepting methods
3.1. Method interception
Figure 3.1. Normal flow: calling a method and returning control Figure 3.2. Intercepted flow: the method interceptor is a middleman 3.1.1. PostSharp method interception
Listing 3.1. Calling Send method on TwitterClient service class Figure 3.3. Console output simulating a tweet Listing 3.2. Indicating which method to intercept with an attribute Figure 3.4. Diagram with a real PostSharp method interception aspect Figure 3.5. Console output with interceptor
3.1.2. Castle DynamicProxy method interception
Listing 3.3. Calling the Send method on the TwitterClient service class Figure 3.6. Console output simulating a tweet again Listing 3.4. Adding code to the interceptor Figure 3.7. Console output with a tweet and interceptors
3.2. Real-world example: data transactions
3.2.1. Ensuring data integrity with begin and commit
Listing 3.5. Three different transaction scenarios Listing 3.6. A Main method to try out the Save scenarios Figure 3.8. Console reporting that the save was successful. Figure 3.9. SaveRetry fails on the first attempt. Figure 3.10. SaveFail will always fail. Listing 3.7. Basic transaction interceptor, used with proxy generator Listing 3.8. Using ProxyGenerator to apply the TransactionWithRetries aspect
3.2.2. When transactions go bad: rollback
Listing 3.9. Using Dispose to rollback
3.2.3. When all else fails, retry
Listing 3.10. Adding a loop to retry Figure 3.11. Success after one retry Listing 3.11. Transaction with maximum retries specified in constructor Figure 3.12. Console reporting that there was one retry before successful save
3.3. Real-world example: threading
3.3.1. The basics of .NET threading 3.3.2. UI threads and worker threads
Figure 3.13. A desktop application Listing 3.12. Full Form1 class with button click event handler Figure 3.14. Because GetTweet runs on the UI thread, the other UI controls are unable to accept input while it’s running. Listing 3.13. Checking whether Invoke is necessary Listing 3.14. Wouldn’t it be nice if threading were more like this?
3.3.3. Declarative threading with AOP
Listing 3.15. UIThread interceptor aspect Listing 3.16. Declarative threading is now a reality Listing 3.17. Changing from Thread to Task
3.4. Summary
Chapter 4. Before and after: boundary aspects
4.1. Boundary aspects
4.1.1. PostSharp method bounding
Listing 4.1. Calling a GetBattingAverage method on a service class Figure 4.1. Console reporting results Listing 4.2. Using an attribute to indicate which method to bound Figure 4.2. Console out with method boundary aspect
4.1.2. Method boundaries versus method interception
Figure 4.3. Side-by-side comparison of a method boundary and a method interception Shared State Between Aspect Methods 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 Figure 4.4. Output of the shared state demo Listing 4.5. Using MethodExecutionTag to share state Figure 4.5. Output using MethodExecutionTag for shared state Clarity/intent of code Listing 4.6. A boundary aspect that overrides only OnExit Listing 4.7. An equivalent interception aspect
4.1.3. ASP.NET HttpModule bounding
Figure 4.6. Demo.aspx in a browser Listing 4.8. Configuring MyHttpModule in Web.config Listing 4.9. Event handlers in MyHttpModule Figure 4.7. Demo.aspx page as viewed in a browser Listing 4.10. Writing text to the response at the beginning and end of a page Figure 4.8. Demo.aspx with HttpModule viewed in a browser
4.2. Real-world example: detecting mobile users
4.2.1. Offer a link to an application
Figure 4.9. Examples of a mobile interstitial when visiting LinkedIn or the Verge Figure 4.10. Routing a mobile user to their preferred experience Create an HttpModule Listing 4.11. Subscribing to the BeginRequest boundary event Check for mobile user Listing 4.12. A class to detect mobile users Redirect to a Mobile Splash Screen Listing 4.13. Detecting a mobile browser Figure 4.11. Display an interstitial to the mobile user Listing 4.14. Basic splash screen with two buttons Listing 4.15. Handling the button clicks in code-behind Adding checks Listing 4.16. Adding checks to avoid redirect loops
4.2.2. Don’t be a pest
Listing 4.17. Checking for a cookie
4.3. Real-world example: caching
Figure 4.12. You might be victim of slow request transit, slow processes, slow response transit, or all of the above Figure 4.13. How a cache helps with a slow process or slow transit 4.3.1. ASP.NET Cache 4.3.2. An application that could benefit from caching
Figure 4.14. A page with a form to look up a car’s market value 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 Figure 4.15. The CarValue.aspx page in a browser Listing 4.22. Clicking the Get Value button Figure 4.16. The CarValue.aspx showing a dollar amount after clicking Get Value
4.3.3. Caching a result
Listing 4.23. Storing the results of the method in a cache Listing 4.24. Naïve GetCacheKey implementation Figure 4.17. After three different requests, the cache contains three values Figure 4.18. How the Cache key is constructed
4.3.4. Retrieving from the cache
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
4.3.5. A more robust cache key
Listing 4.28. A more robust GetCacheKey using serialization Figure 4.19. Serialized object used for cache keys
4.4. Summary
Chapter 5. Get this instead: intercepting locations
5.1. Location interception
5.1.1. Fields and properties in .NET
Listing 5.1. Encapsulation of a private field with methods Listing 5.2. The compiled program viewed through the ILSpy tool
5.1.2. PostSharp location interception
Listing 5.3. Using a method interception aspect on a property Figure 5.1. The Console output of method interception on a property Listing 5.4. Using a PostSharp location interception aspect
5.2. Real-world example: lazy loading
5.2.1. Lazy loading approaches in .NET
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>
5.2.2. Implementing lazy loading with AOP
Listing 5.8. Basic Console application with no lazy loading Figure 5.2. Output with no lazy-loading Listing 5.9. A lazy-loading aspect Figure 5.3. Output with lazy-loading
5.2.3. What about lazy-loading fields?
Listing 5.10. Lazy loading using Activator Listing 5.11. SlowConstructor with a dependency on IMyService Listing 5.12. Initializing Listing 5.13. Lazy loading with StructureMap Listing 5.14. Using StructureMap in place of Activator Figure 5.4. Lazy loading with dependencies via StructureMap
5.3. Real-world example: INotifyPropertyChanged
5.3.1. Using INotifyPropertyChanged in a desktop application
Figure 5.5. MainWindow layout with text boxes and labels 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 Figure 5.6. Type in first and last name, and watch the full name populate
5.3.2. Problems and constraints with INotifyPropertyChanged
Listing 5.20. Using CallerMemberName attribute
5.3.3. Reducing boilerplate with AOP
Figure 5.7. Installing NotifyPropertyWeaver 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 Listing 5.25. RaisePropertyChanged method
5.4. Summary
Chapter 6. Unit testing aspects
6.1. Writing tests with NUnit
6.1.1. Writing and running NUnit tests
Listing 6.1. Writing a test of the Reverse method Figure 6.1. The NUnit test runner UI Figure 6.2. One failing test Figure 6.3. One passing test
6.1.2. Testing strategies for aspects
Listing 6.2. Testing for the presence of attributes
6.2. Castle DynamicProxy testing
6.2.1. Testing an interceptor
Listing 6.3. A static Log class Listing 6.4. NUnit fixture to test MyInterceptor Listing 6.5. Using Moq
6.2.2. Injecting dependencies
Putting inversion of control to work Figure 6.4. Dependency diagram of a more complex domain Implement the services Listing 6.6. MyOtherService service implementation and interface Listing 6.7. LoggingService implementation and interface Write the logging aspect Listing 6.8. MyLoggingAspect implementation Unit testing the aspect Listing 6.9. Testing MyLoggingAspect Create the MyService class Listing 6.10. MyService implementation and interface Listing 6.11. Using MyService object in Main Using an IOC tool to manage the dependencies Listing 6.12. Initializing and using StructureMap Using DynamicProxy with StructureMap Listing 6.13. One approach to using aspects with a complex domain Refactor using EnrichWith Listing 6.14. Using EnrichWith feature of StructureMap Listing 6.15. More concise use of EnrichWith A ProxyHelper Listing 6.16. ProxyHelper
6.3. PostSharp testing
6.3.1. Unit testing a PostSharp aspect
Listing 6.17. A test of a PostSharp aspect
6.3.2. Injecting dependencies
Listing 6.18. Program’s Main method Listing 6.19. MyLoggingAspect with PostSharp Listing 6.20. Dependency inversion via RuntimeInitialize Figure 6.5. Correct Console output 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
6.3.3. Problems with PostSharp and testing
Compile-time weaving 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 Workaround by turning off PostSharp Listing 6.27. Workaround with custom symbols Listing 6.28. A global variable setting for unit testing Inaccessible constructors Testing PostSharp indirectly Figure 6.6. A fat aspect and a thin aspect Listing 6.29. A thin aspect and the interface to which it’s delegating
6.4. Summary
Part 3. Advanced AOP concepts Chapter 7. AOP implementation types
7.1. How does AOP work?
Figure 7.1. A high-level diagram of AOP
7.2. Runtime weaving
Figure 7.2. A proxy class constructed at runtime 7.2.1. Proxy pattern revisited
Figure 7.3. The proxy pattern
7.2.2. Dynamic proxies
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 Figure 7.4. The output after creating a proxy class at runtime
7.3. Compile-time weaving
Figure 7.5. From C# to CIL to the CLR Figure 7.6. The same process from figure 7.5 with PostSharp added 7.3.1. Postcompiling
Figure 7.7. From source to assembly to execution
7.3.2. Before and after
Figure 7.8. Decompiling an assembly with ILSpy Listing 7.9. Introducing a PostSharp aspect Figure 7.9. Decompiling an assembly that’s been modified with PostSharp Listing 7.10. ILSpy decompile of MyClass
7.4. Runtime versus compile-time weaving
7.4.1. Pros of runtime weaving 7.4.2. Pros of compile-time weaving
7.5. Summary
Chapter 8. Using AOP as an architectural tool
8.1. Compile-time initialization and validation
Figure 8.1. Build process with PostSharp Figure 8.2. Zooming into the post-compiler steps of PostSharp aspects Note 8.1.1. Initializing at compile time
Listing 8.1. Logging the method that was called Listing 8.2. Using Initialize to get the method name at compile time
8.1.2. Validating the correct use of an aspect
Listing 8.3. A LocationInterceptionAspect to log usage of get Listing 8.4. Using CompileTimeValidate to check the location name Figure 8.3. CompileTimeValidate-generated error message
8.1.3. Real-world example: Threading revisited
Listing 8.5. Runtime checks on casting Listing 8.6. Threading aspect of compile-time validation Figure 8.4. UIThread validation error message
8.2. Architectural constraints
8.2.1. Enforcing architecture
Scalar constraints Referential constraints Table 8.1. PostSharp out-of-the-box architectural constraints Listing 8.7. Unsealable referential constraint Listing 8.8. Unsealable demonstration Figure 8.5. Error caused by trying to seal an Unsealable class
8.2.2. Real-world example: NHibernate and virtual
Figure 8.6. The InvalidProxyTypeException of death Figure 8.9. Multicasting at the class level Listing 8.9. NHibernate ScalarConstraint Listing 8.10. An NHibernate entity with a nonvirtual property Figure 8.7. Result of NHEntity scalar constraint
8.3. Multicasting
Figure 8.8. Pointcuts on a low-level flowchart 8.3.1. At the class level
Figure 8.10. Aspect applied to the constructor and three methods Listing 8.11. Excluding a member with AttributeExclude Figure 8.11. No aspect applied to Method3 Listing 8.12. AspectPriority for ordering Figure 8.12. Swapping AspectPriority Listing 8.13. AttributeTargetElements to target only the instance constructor
8.3.2. At the assembly level
8.4. Summary
Chapter 9. Aspect composition: example and execution
Listing 9.1. Multiple aspects on the same method 9.1. Using multiple aspects
Table 9.1. Ordering of aspects Figure 9.1. Scenario: caching first Figure 9.2. Scenario: authorization first
9.2. Aspect roles with PostSharp
9.2.1. PostSharp aspect roles
Listing 9.2. Specifying an aspect role
9.2.2. Role dependencies
Listing 9.3. Specifying aspect role dependency Listing 9.4. An aspect that requires another role Figure 9.3. Failed aspect dependency
9.3. Composing aspects with DynamicProxy
Listing 9.5. ProxyHelper from chapter 6 9.3.1. Ordering aspects
Listing 9.6. A demo class and two demo aspects Listing 9.7. Use of multiple aspects on the same code in StructureMap Figure 9.4. A diagram of what gets returned by StructureMap Figure 9.5. Switching the order of Aspect1 and Aspect2
9.3.2. Reducing repetition with custom conventions
Class name convention 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 Namespace Convention Listing 9.11. Using a namespace-based convention
9.4. Real-world example: caching and authorization
9.4.1. Application architecture
Figure 9.6. The correct ordering of authorization and caching. Figure 9.7. A high-level view of the architecture Dependency configuration Listing 9.12. Configure StructureMap with default conventions Services Listing 9.13. Budget service, interface, and implementation Listing 9.14. A static caching service Listing 9.15. User repository Console UI Listing 9.16. The main UI of the program Listing 9.17. The main UI prepared for exception Concerns Note 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
9.4.2. PostSharp
Listing 9.24. PostSharp caching aspect Listing 9.25. PostSharp method context adapter Figure 9.8. The thin logging aspect, repeated from chapter 6 Figure 9.9. Execution, using budget service with caching aspect Listing 9.26. PostSharp authorization aspect Note Figure 9.10. Execution again, with caching and authorization aspects, undefined composition Listing 9.27. Aspect composition of caching and authorization Figure 9.11. Execution, with authorization and caching composed correctly
9.4.3. Castle DynamicProxy
Write two new aspects 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 Remove PostSharp attributes Change IoC configuration Listing 9.32. Another Proxify overload in ProxyHelper Listing 9.33. Name a mapping for Manager authorization Listing 9.34. Complete IoC initialization Figure 9.12. Execution with Auth and Cache aspects, using Castle DynamicProxy
9.5. Summary
Appendix A. Ecosystem of .NET AOP tools
A.1. Compile-time AOP tools
A.1.1. PostSharp A.1.2. LinFu
Listing A.1. Simple LinFu example Listing A.2. Modifying project file to add PostWeaveTask
A.1.3. SheepAspect
Listing A.3. Simple SheepAspect example
A.1.4. Fody
Listing A.4. Simple MethodDecorator example
A.1.5. CIL manipulation tools
Mono.Cecil PostSharp SDK Microsoft CCI
A.2. Runtime AOP tools
A.2.1. Castle Windsor/DynamicProxy
Listing A.5. A basic Castle Windsor and DynamicProxy example
A.2.2. StructureMap
Listing A.6. StructureMap interception
A.2.3. Unity
Listing A.7. Unity interception example
A.2.4. Spring.NET
Listing A.8. Spring.NET example Listing A.9. Spring.NET configuration
Appendix B. NuGet basics
B.1. Introduction to NuGet
B.1.1. Installing NuGet
Figure B.1. Installing Nuget from NuGet.org Figure B.2. Install NuGet from Extension Manager
B.1.2. Installing packages with NuGet UI
Figure B.3. Installing a package with the NuGet UI
B.1.3. Install packages with Package Manager Console
Figure B.4. Opening the Package Manager Console
B.2. NuGet package restore
B.2.1. Solution Explorer
Figure B.5. Always show solution in Visual Studio
B.2.2. Enabling package restore
Figure B.6. Enabling package restore feature
B.2.3. What package restore does
Figure B.7. Enabling downloading of missing packages
Index
A B C D E F G H I J K L M N O P Q R S T U V W X
List of Figures List of Tables List of Listings
  • ← Prev
  • Back
  • Next →
  • ← Prev
  • Back
  • Next →

Chief Librarian: Las Zenow <zenow@riseup.net>
Fork the source code from gitlab
.

This is a mirror of the Tor onion service:
http://kx5thpx2olielkihfyo4jgjqfb7zx7wxr3sd4xzt26ochei4m6f7tayd.onion