Logging using AOP in .NET Core 2.1

user2661305 picture user2661305 · Aug 10, 2018 · Viewed 10.2k times · Source

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.

Answer

aseaSharp picture aseaSharp · Aug 10, 2018

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));
    }
}