Aspect Oriented Programming (AOP) is a very powerful approach to avoid boilerplate code and archive better modularity. The main idea is to add behavior (advice) to the existing code without making any changes in the code itself. AOP provides a way of weaving an aspect into the code. An aspect is supposed to be generic so it can be applied to any object and object should not have to know anything about advice. AOP allows us to separate cross-cutting concerns and makes it easier to follow Single Responsibility Principle (one of the SOLID principles). Logging, security, transactions and exceptions handling are the most common examples of using AOP. If you are not familiar with this programming technique you can read this. It could be very useful because this article talks mostly about how to use AOP in C# rather than what AOP is. Don’t be scared if you still do not understand what it is all about. After looking at several examples, it becomes much easier to understand.
In Java, AOP is implemented in AspectJ and Spring frameworks. There are PostSharp (not free), NConcern, and some other frameworks (not very popular and easy to use) to do almost the same in .NET.
It is also possible to use RealProxy class to implement AOP. You can find some examples of how to do it.
Example1
Aspect-Oriented Programming: Aspect-Oriented Programming with the RealProxy Class.
This article also contains a lot of explanation of what is AOP, how Decorator Design Pattern works, and examples of implementing logging and authentication using AOP.
Example2
MSDN.
Unfortunately, these examples have some significant drawbacks. Example1 does not support out parameters. Example2 has limitation: decorated class should be inherited from MarshalByRefObject (it could be a problem if it is not class designed by you). Also, both examples do not support asynchronous functions as expected. Several months ago, I changed the first example to support Task results and output parameters and wrote article about it.
Example3
Aspect Oriented Programming in C# with RealProxy.
Unfortunately, .NETCore does not have RealProxy class. There is DispatchProxy class instead. Using of DispatchProxy class is a bit different than using RealProxy class.
Let’s implement logging using DispatchProxy class.
Code of this articles and example of using RealProxy with unit tests for both can be found on GitHub.
Solution Extension to log exception (Extensions.cs)
Conclusion
This code works in my case. If you have any examples when this code does not work, or you have ideas on how this code could be improved – feel free to contact me.