0

I have a lot of code I want to add logging to. My plan was to use Unity or Castle.Windsor to create an intercepted logging routine, and to add it to existing code by using a custom C# attribute. I cannot change the existing code structure (but I can add startup configuration to it, so the container registration approach is OK).

This didn't look possible with Unity without changing the call structure (getting the intercepted class required changing the instantiation to use registered dependency injection), so I'm trying Castle.Windsor. This code I have is not firing the Intercept routine.

This gave me some hope that it will be possible in Castle.Windsor: Inject logging dependency with Castle Windsor

using System;
using Castle.Core;
using Castle.DynamicProxy;
using Castle.MicroKernel.Registration;
using Castle.Windsor;

namespace UnityTestProject
{
    class Program
    {
        private static WindsorContainer container;

        static void Main(string[] args)
        {
            container = new WindsorContainer();
            container.Register(Component.For<MyLogger>().LifeStyle.Transient);

            ICalcService c = new Calc();
            Console.WriteLine(c.Add(3,4));
            Console.ReadKey();
        }
    }

    public class MyLogger : IInterceptor
    {
        public void Intercept(IInvocation invocation)
        {
            Console.WriteLine("Inovaction called!");
            invocation.Proceed();
        }
    }

    public interface ICalcService
    {
        int Add(int x, int y);
    }

    public class Calc : ICalcService
    {
        [Interceptor(typeof(MyLogger))]
        public int Add(int x, int y)
        {
            return x + y;
        }
    }
}

Is there a better way for me to do this logging injection? PostSharp weaving would be ideal, but I cannot use it (expense and licensing).

Community
  • 1
  • 1
flacnut
  • 1,030
  • 4
  • 11
  • 21
  • I read your constraint about not being able to change the code structure, but for long term code improvements, I think you should really think about designing your application around a few cleverly chosen generic interfaces. This makes it much easier to add cross-cutting concerns such as logging to your application later on. Take a look for instance at [this](http://bit.ly/s7tGEH), [this](http://bit.ly/s3UUyv), and [this](http://bit.ly/RrJRvD) article. – Steven Jun 28 '13 at 08:44

1 Answers1

2

changed main to :

container = new WindsorContainer();
container.Register(
    Component.For<ICalcService>().ImplementedBy<Calc>().Interceptors<MyLogger>(),
    Component.For<MyLogger>().LifeStyle.Transient);

ICalcService c = container.Resolve<ICalcService>();
Console.WriteLine(c.Add(3, 4));
Console.ReadKey();

And you can remove the interceptor attribute. If you want to do interception with windsor then Windsor must be allowed to created the component(s).

Marwijn
  • 1,681
  • 15
  • 24
  • Yep, this 'container.Resolve()' is what I was hoping not to have to do, but in the long run I can see that it is better. I just need to get the rest of my team on board. This pretty much looks like Unity to me now though, almost identical syntax. Is there much difference between Unity and Windsor? Actually, I found this and it answers my question: http://stackoverflow.com/questions/2216684/comparing-castle-windsor-unity-and-structuremap – flacnut Jun 28 '13 at 19:02