views:

2171

answers:

4

Hi guys

I'm fairly new to Castle Windsor and am looking into the in's and out's of the logging facility. It seems fairly impressive but the only thing i can't work out is where Windsor sets the Logger property on my classes. As in the following code will set Logger to the nullLogger if the class hasn't been setup yet but when Resolve is finished running the Logger property is set.

private ILogger logger;

public ILogger Logger
{
    get
    {
        if (logger == null) 
            logger = NullLogger.Instance;
        return logger;
    }
    set { logger = value; }
}

So what I am wondering is how and where windsor sets my Logger property.

Cheers Anthony

+4  A: 

The logger is setup by the logging facility, which is in the <facilities> section of the configuration. For example to use log4net your app or web.config would look something like this:

<?xml version="1.0"?>
<configuration>
    <configSections>
        <section name="castle" type="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler, Castle.Windsor"/>
    </configSections>
<Configuration>

<castle>

    <facilities>
        <facility id="loggingfacility" 
             type="Castle.Facilities.Logging.LoggingFacility, Castle.Facilities.Logging" 
             loggingApi="log4net" 
             configFile="logging.config" />
    </facilities>

</castle>
</configuration>
Todd
A: 

Cheers for the response. I have a config that looks almost exactly like this. More what I mean is where abouts in the source code and where in the windsor lifecycle does it set the property.

Thanks Anthony

vdhant
A: 

Since you have a public Property with a Setter, every time you resolve your object from Windsor, it will also try to set any public properties with appropriate values from the container (in your case, an ILogger which your facility will populate into Windsor).

Meaning, if you resolve the Class from Windsor, this will be set. But not if you do new Class().

That's atleast how I understand it.

The other approach is to use constructors, meaning if you have a constructor named

public Class(ILogger logger) it will be instantiated with ILogger as a parameter.

jishi
+4  A: 

You can also configure this programatically when you initialise windsor (e.g. from your global.asax.cs):

container.AddFacility("logging",  new LoggingFacility(LoggerImplementation.Log4net));

You can of course choose any of the logger implimentations.

This this will be wired up whenever windsor instantiates any class expecting a logger. I wouldn't put this in the constructor as it's a cross cutting concern - better to do like you suggested in my opinion. You can simplify it a little:

    private ILogger logger = NullLogger.Instance;
    public ILogger Logger
    {
        get { return logger; }
        set { logger = value; }
    }
UpTheCreek
The getter is redundant. The only reason this property exists is so that Windsor can override the default null logger.
IanT8