PostSharp - il weaving - thoughts
Asked Answered
D

3

10

I am considering using Postsharp framework to ease the burden of application method logging. It basically allows me to adorn methods with logging attribute and at compile time injects the logging code needed into the il. I like this solution as it keeps the noise out of the deign time code environment. Any thoughts, experiences or better alternatives?

Delrosario answered 18/9, 2008 at 11:5 Comment(2)
I was thinking the same thing. Would love to hear what people think.Fairlie
Yeah bugged me for a few weeks - but I think the overhead at compile time is well worth the lack of logging code, be great to hear if anyone has used it.Delrosario
S
7

I apply logging with AOP using Castle Windsor DynamicProxies. I was already using Castle for it's IoC container, so using it for AOP was the path of least resistence for me. If you want more info let me know, I'm in the process of tidying the code up for releasing it as a blog post

Edit

Ok, here's the basic Intercepter code, faily basic but it does everything I need. There are two intercepters, one logs everyhing and the other allows you to define method names to allow for more fine grained logging. This solution is faily dependant on Castle Windsor

Abstract Base class

namespace Tools.CastleWindsor.Interceptors
{
using System;
using System.Text;
using Castle.Core.Interceptor;
using Castle.Core.Logging;

public abstract class AbstractLoggingInterceptor : IInterceptor
{
    protected readonly ILoggerFactory logFactory;

    protected AbstractLoggingInterceptor(ILoggerFactory logFactory)
    {
        this.logFactory = logFactory;
    }

    public virtual void Intercept(IInvocation invocation)
    {
        ILogger logger = logFactory.Create(invocation.TargetType);

        try
        {
            StringBuilder sb = null;

            if (logger.IsDebugEnabled)
            {
                sb = new StringBuilder(invocation.TargetType.FullName).AppendFormat(".{0}(", invocation.Method);

                for (int i = 0; i < invocation.Arguments.Length; i++)
                {
                    if (i > 0)
                        sb.Append(", ");

                    sb.Append(invocation.Arguments[i]);
                }

                sb.Append(")");

                logger.Debug(sb.ToString());
            }

            invocation.Proceed();

            if (logger.IsDebugEnabled && invocation.ReturnValue != null)
            {
                logger.Debug("Result of " + sb + " is: " + invocation.ReturnValue);
            }
        }
        catch (Exception e)
        {
            logger.Error(string.Empty, e);
            throw;
        }
    }
}
}

Full Logging Implemnetation

namespace Tools.CastleWindsor.Interceptors
{
using Castle.Core.Logging;

public class LoggingInterceptor : AbstractLoggingInterceptor
{
    public LoggingInterceptor(ILoggerFactory logFactory) : base(logFactory)
    {
    }
}
}

Method logging

namespace Tools.CastleWindsor.Interceptors
{
using Castle.Core.Interceptor;
using Castle.Core.Logging;
using System.Linq;

public class MethodLoggingInterceptor : AbstractLoggingInterceptor
{
    private readonly string[] methodNames;

    public MethodLoggingInterceptor(string[] methodNames, ILoggerFactory logFactory) : base(logFactory)
    {
        this.methodNames = methodNames;
    }

    public override void Intercept(IInvocation invocation)
    {
        if ( methodNames.Contains(invocation.Method.Name) )
            base.Intercept(invocation);
    }
}
}
Shine answered 18/9, 2008 at 11:8 Comment(5)
Hi Be great if you could give a quick demo - does it work with attributes over methodsDelrosario
I'm not keen on using Attribute's for dealing with cross-cutting concersn like logging, validation, etc. I use an external DSL based on Boo for configuring the IoC Container and I assign logging there. This means I can add/remove logging without chaning C#Shine
cheers for the quick response. Feels like I will get into a world of xml config pain introducing castle and IOC just for logging.Delrosario
Noooo, just say NO! Castle has a Fluent Interface and a DSL. I'm a huge fan of the DSL, it's called Binsor and you can find more info here: ayende.com/Blog/archive/7268.aspx If you post any Q's on Binsor I'll prolly be able to help you outShine
PostSharp is more comprehensive in term of the mechanism of performing AOP. Autofac Castle core does not support IL code weaving so you won't be able to log inner method calls!Lynea
R
6

+1 on postsharp. Have been using for several things (including some attempts on adding preconditions and postconditions to C# code) and don't know how I'd make it without it...

Rittenhouse answered 25/9, 2008 at 20:9 Comment(0)
W
5

It depends to an extent on how long you'll be developing and supporting the project for. Sure, IL weaving is a nice technology, but what happens if the IL and/or assembly metadata format changes again (as it did between 1.1 and 2.0) and those changes make the tool incompatible with the new format.

If you depend on the tool then it prevents you from upgrading your technology until the tool supports it. With no guarantees in place about this (or even that development will continue, though it does seem likely) then I'd be very wary about using it on a long term project.

Short term, no problem though.

Willey answered 25/9, 2008 at 20:25 Comment(2)
Since PostSharp is open source, development can/will continue as long as you depend on it.Wholesome
That's true in theory, but unfortunately theory and practice are not always the same. NDoc is open source, and was once thriving, but now lies dormant. Open source projects still need a community around them, and if you depend on it, then you may be left maintaining it. Do you want that burden?Willey

© 2022 - 2024 — McMap. All rights reserved.