How to Use Aspect Oriented Programming in C#?
I have been fortunate enough that my programming tasks were simple. All my projects were for the Internet, which meant that my classes only had to handle one or two aspects of my programs. I always had a main function to dump global instructions and procedures. Object-oriented programming (OOP) with a little web scripting did everything I needed without much code rewriting.
However, I know not every program is as easy to develop. Some require runtime tasks that must be done at every method call. While you can create special classes to handle these tasks, you still have to write the code that calls these classes in each and every class and method you write. Fortunately, we have aspect-oriented programming. By adding some aspect-oriented programming in your C# code, you can kis your programming nightmares goodbye.
Learn how to use OOP strategies in C# at Udemy
What is Aspect Oriented Programming?
Reusability is not a new concept. If you have been programming for some time, your programs already contain several pieces of reusable code that you created over the years. For most of us, OOP gave us all we need. We established each class as a single purpose object and set our main function to call these objects as needed. Life was good until we needed to do something more complicated like logging the execution of a program.
For an application execution trace, we need to log the names of each and every method as they are called as well as such things as how much time it took to execute the method. So, we write a simple logger class to handle these tasks.
Our logger class will have methods that will do such things as BeginLog, EndLog. These methods will record the class being logged into a file or database. Now, we let each method of our program execute these logger methods, once at the start and once just before they return control back to our main function. We also implement reflections to track the calling methods.
We now have something that looks like this:
class BusinessModule{ … Core data methods BeginLog(); Public static void method1() { … BeginLog(); … Perform core operation … EndLog(); } public static void method2() { … BeginLog(); … Perform core operation … EndLog(); } }
As you can see, even with reusable code, we have to do lots of coding to get the logger to work as advertised. We can remove some of this repetitive code by using some aspect oriented programming C# techniques. We create attributes and aspect such as “LogEnable” to take care of the logging code for us.
Developed in the 1990s, aspect-oriented programming (AOP) provides us attribute/ aspect components we can use in our classes at every level. These aspects exist as metadata for our classes which we can implement at run time to provide the required services on an as needed basis.
Learn about other ways you can extend the .Net Framework at Udemy
Aspect Oriented Programming in C#
AOP handles aspects as component frameworks. It uses something called an aspect wrapper to insert our aspect methods into our classes at compile time. However, C# does come with an aspect wrapper. C# is a hybrid procedural and object-oriented programming language. Therefore, we have to mimic AOP using a combination of special classes, namespaces, and interfaces.
First, we must inherit our AOP-enabled classes from the ContextBoundClass. The ContextBoundClass class lets us build AOP components by letting us extend the .Net Framework providing the metadata for our components.
public class ContextClass: ContextBoundObject { }
We add our metadata to this class where we need to implement our aspect methods. In C#, we create our aspect modules as attribute classes. As you see below, our attribute classes will have their own attributes. In our example, the AttributeTarget attribute controls the application of the attribute to class/method/property and so on.
[AttributeUsage(AttributeTargets.Class)] public class ContextAtrbAttribute :Attribute { private string _fileName; public ContextAtrbAttribute(string fileName) { this._fileName = fileName; } }
Understand how to implement C# interfaces at Udemy
Contexts in C#
C# implements AOP through contexts. Contexts are logical groupings of the objects with the same aspect values. They establish the places where our aspect interceptors can intercept their calls from our objects. Objects with different contexts can still communicate with each other but only through the .Net context architecture.
.Net transmits data between contests through chains of message sinks which we can custom build as we please. These sinks pass our message data from sink to sink until it reaches the end of the chain, and it is here where we insert our aspect interceptors.
The C# run-time sets up this chain of message sinks the moment we set our classes to inherit ContextBoundObject. It also sets up proxy objects to help facilitate communication between our contests. The transparent proxy takes the message from the runtime and serializes it into the stack before sending it on to the real proxy. The real proxy represents our class in the message sink channel. It passes the messages to the sinks in the channel for processing. Each sink can preprocess the message before sending it onto the next sink in the chain. At the end, the stack builder sink de-serializes the message into the stack and calls the program class’ method. Run time then reverses the process and sends the parameter and return values back through the chain for post processing.
At any step in the chain, we can implement our aspect oriented programming attribute methods. We do this by first setting up some prerequisites and then adding a few event triggers to our program classes. All of our prerequisites fall under the following System.Runtime.Remoting namespaces. So, you want to include them in all your AOP classes.
using System.Runtime.Remoting.Contexts; using System.Runtime.Remoting.Activation; using System.Runtime.Remoting.Messaging;
We then have to make sure our main classes inherit ContextBoundObject so they understand and can call our AOP procedures. We then have to create our aspect classes making sure they all implement the IContextAttribute interface and inherit from the Attribute class. We then add in our context properties by implementing the IContextProperty and IContributeObjectSink interfaces. Finally, we develop our message sinks using the IMessageSink interface to complete the aspect. From that point on, all we need to do is write our code. If we implemented these inheritances and interfaces correctly we will have aspect oriented programming C# classes on our hands.
Recommended Articles
Top courses in C# (programming language)
C# (programming language) students also learn
Empower your team. Lead the industry.
Get a subscription to a library of online courses and digital learning tools for your organization with Udemy Business.