D3C34C34D
D3C34C34D

Reputation: 417

Installing Windsor Logging Facility into a library

I'm developing a framework where I've put lots of logging throughout. I used Castle Windsor's ILogger through this property pattern:

namespace Framework
{
    public class SomeClass
    {
        private ILogger _logger = NullLogger.Instance;
        public ILogger Logger
        {
            get { return _logger; }
            set { _logger = value; }
        }

        public void DoSomething()
        {
            Logger.Info("Doing something.");
        }

        //...

    }
}

I also provide an installer from within the framework:

namespace MyFramework
{
    public class LoggerInstaller : IWindsorInstaller
    {
        private readonly string _configPath;

        public LoggerInstaller(string configPath)
        {
            _configPath = configPath;
        }

        public void Install(IWindsorContainer container, IConfigurationStore store)
        {
            container.AddFacility("logging", new LoggingFacility(LoggerImplementation.Log4net, _configPath));
            //I've also tried this one:
            //container.AddFacility<LoggingFacility>(f => f.LogUsing(LoggerImplementation.Log4net).WithConfig(_configPath));
        }
    }
}

This project is then referenced from other projects. For example, in the test project, I'll construct a test by first installing the logger. I do this with an abstract class that all of my long running tests extend:

namespace Framework.Test
{
    public abstract class Log4NetLoggedTest
    {
        private const string ConfigFilePath = "log4net.config";
        protected ILogger Logger { get; set; }
        protected IWindsorContainer Container { get; set; }

        protected Log4NetLoggedTest()
        {
            Container = new WindsorContainer();

            Container.Install(new LoggerInstaller(ConfigFilePath));

            Logger = Container.Resolve<ILogger>();
        }

        ~Log4NetLoggedTest()
        {
            Container.Dispose();
        }
    }
}

So that my test looks like this:

namespace Framework.Test
{
    [TestFixture]
    public class MyLongRunningTest : Log4NetLoggedTest
    {
        [Test]
        [Category("LongRunning")]
        public void ModelConvergesForS50()
        {
            Logger.Info("Starting test...");

            var obj = new SomeClass();
            obj.DoSomething();

            // ...
        }
    }
}

The test's ILogger Logger gets resolved and set properly, so in this example I get the "Starting test..." but not the "Doing something." The SomeClass's ILogger stays as a NullLogger.

Please help!

Upvotes: 3

Views: 662

Answers (2)

Robert Levy
Robert Levy

Reputation: 29073

You are instantiating SomeObj with 'new' rather than going through the container. If you don't go through the container, it can't inject the dependency

Upvotes: 2

marcelo-ferraz
marcelo-ferraz

Reputation: 3257

I may be saying something stupid, but, shouldnt be something like:

namespace Framework.Test
{
    [TestFixture]
    public class MyLongRunningTest : Log4NetLoggedTest
    {
        [Test]
        [Category("LongRunning")]
        public void ModelConvergesForS50()
        {
            Logger.Info("Starting test...");

            var obj = new SomeClass();
            obj.Logger = Logger;
            obj.DoSomething();

            // ...
        }
    }
}

I couldn't see you applying that instance of the logger that you use inside the class anywhere.

Upvotes: 0

Related Questions