📜 ⬆️ ⬇️

Aspect-oriented programming. Postsharp

Aspect-oriented programming

AOP is a programming paradigm, which is based on the idea of ​​separating the end-to-end functionality into separate entities - aspects. A pass-through is called a functional distributed across different parts of the program. Examples of end-to-end functionality include the tasks of logging, tracing, exception handling, checking preconditions and postconditions in contract programming, and checking access rights. AOP can also be used to solve problems of protection and multithreading.

Postsharp

The PostSharp framework is an implementation of an aspect-oriented approach for .NET. PostSharp, unlike many of its analogs, works as a post-compiler, that is, it makes changes to MSIL (Microsoft Intermediate Language).
PostSharp makes it easy to create attributes that change the behavior of methods, fields, and types. To do this, you need to inherit the attribute class from one of the base classes provided by the library, implement its virtual methods and apply this attribute.


Example 1:
using System; using PostSharp.Aspects; namespace HelloAspects { class Program { private static void Main() { hello(); } [SayGoodbye] private static void hello() { Console.WriteLine("Hello!"); } } [Serializable] class SayGoodbyeAttribute : OnMethodBoundaryAspect { public override void OnExit(MethodExecutionArgs args) { Console.WriteLine("Goodbye."); } } } 

As a result, the console will display:
')
  Hello!
 Goodbye 

This example shows how the behavior of the hello () method has changed using the SayGoodbye attribute.

The OnExit method is called advice, it is always executed (even if an exception is thrown, since OnExit is called from the finally block) after the body of the method to which the attribute is applied. Besides it, the OnMethodBoundaryAspect class provides three more tips:

Although Example 1 illustrates some of the features of PostSharp, there are few practical benefits. Example 2 shows the implementation of tracing using AOP.

Example 2:
 using System; using System.Diagnostics; using PostSharp.Aspects; namespace HelloAspects { class Program { private static void Main() { Trace.Listeners.Add(new TextWriterTraceListener(Console.Out)); hello(); } [Trace] private static void hello() { Console.WriteLine("Hello!"); } } [Serializable] public class TraceAttribute : OnMethodBoundaryAspect { public override void OnEntry(MethodExecutionArgs args) { Trace.WriteLine(string.Format("Entering {0}.{1}.", args.Method.DeclaringType.Name, args.Method.Name)); } public override void OnExit(MethodExecutionArgs args) { Trace.WriteLine(string.Format("Leaving {0}.{1}.", args.Method.DeclaringType.Name, args.Method.Name)); } } } 


What is the advantage of using AOP in this example? Imagine that we have several classes, each of which has many methods and we need to implement a trace. If you do not use AOP, then you have to prescribe Trace.WriteLine in the body of each method ... Using AOP, we separate this end-to-end functionality into a separate entity (aspect) and apply it to methods using an attribute.

Of course, PostSharp has aspects beyond OnMethodBoundaryAspect:

PostSharp is a handy tool for integrating AOP into programs written using the .NET environment. AOP complements OOP, highlighting the end-to-end functionality into separate aspects, eliminates code duplication (DRY — Don't Repeat Yourself) and simplifies the application architecture.

PS This post was written on the basis of the study work that I did at the institute.

Source: https://habr.com/ru/post/111130/


All Articles