I want to implement AOP for the logging in my .NET Core 2.1 solution. I've never used it before and I've been looking online and cant seem to see any examples of people using it with Core 2. Does anyone know how i would go about this?
For example what packages to use for AOP and have any example code to get me started? Im using the built in DI with .net core so i dont need to worry about that part.
Microsoft DI does not offer advances scenarios such as interceptor or decorators(there is a workaround for decorators using Microsoft DI: https://medium.com/@willie.tetlow/net-core-dependency-injection-decorator-workaround-664cd3ec1246).
You can implement AOP by using Autofac (https://autofaccn.readthedocs.io/en/latest/advanced/interceptors.html) or Simple injector with dynamic proxy. Both have a really good documentation. Simple injector doesn't have an out of the box solution for interception because of their design rules but you can add an extension for it (http://simpleinjector.readthedocs.io/en/latest/aop.html).
Here is a basic AOP scenario from the official SI documentation:(http://simpleinjector.readthedocs.io/en/latest/InterceptionExtensions.html) :
//Add registration to the composition root
container.InterceptWith<MonitoringInterceptor>(serviceType => serviceType.Name.EndsWith("Repository"));`
// Here is an example of an interceptor implementation.
// NOTE: Interceptors must implement the IInterceptor interface:
private class MonitoringInterceptor : IInterceptor {
private readonly ILogger logger;
public MonitoringInterceptor(ILogger logger) {
this.logger = logger;
}
public void Intercept(IInvocation invocation) {
var watch = Stopwatch.StartNew();
// Calls the decorated instance.
invocation.Proceed();
var decoratedType = invocation.InvocationTarget.GetType();
this.logger.Log(string.Format("{0} executed in {1} ms.",
decoratedType.Name, watch.ElapsedMilliseconds));
}
}
Microsoft does not provide an AOP solution out the box for Net Core. However, I have produced a 3rd party project which may help. It works directly with Net Core and plugs in via the ServiceCollection registration in your application.
What Microsoft does provide is a library called System.Runtime.DispatchProxy which can be used to create proxy objects for your classes. However, this proxy isnt particularly useful or feature rich on its own and would require a lot of extra code to get something that is on a level with Castle Proxy (the well known Dynamic Proxy library)
With that in mind, I have created a library which wraps the DispatchProxy into code that can be easily injected during the ServiceCollection configuration in the application startup. The trick is to have a way to create attributes AND a paired interceptor that can be applied to your methods. The attribute is then read during the Proxy wrapping and the relevant Interceptor is called.
This is an example Interceptor Attribute
public class ConsoleLogAttribute : MethodInterceptorAttribute
{
}
This is an example Interceptor class
public class ConsoleLogInterceptor : MethodInterceptor
{
public override void BeforeInvoke(IInterceptionContext interceptionContext)
{
Console.WriteLine($"Method executing: {interceptionContext.CurrentMethod.Name}");
}
public override void AfterInvoke(IInterceptionContext interceptionContext, object methodResult)
{
Console.WriteLine($"Method executed: {interceptionContext.CurrentMethod.Name}");
}
}
This is how it would be applied to your method
[ConsoleLog]
public void TestMethod()
{
}
And then finally, this is how it would be added to your ServiceCollection configuration (assuming that the class you wanted to Proxy was called [TestClass]:
public void ConfigureServices(IServiceCollection services)
{
// Configure Simple Proxy
services.EnableSimpleProxy(p => p.AddInterceptor<ConsoleLogAttribute, ConsoleLogInterceptor>());
// Configure your services using the Extension Methods
services.AddTransientWithProxy<ITestClass, TestClass>();
}
Take a look at this GitHub project: https://github.com/f135ta/SimpleProxy
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With