how to wrap ILogger

484 views
Skip to first unread message

craig p

unread,
Oct 31, 2013, 3:25:22 PM10/31/13
to castle-pro...@googlegroups.com
Hi -

I would like to wrap ILogger with my own interface (in my own namespace) so I can expose a custom interface (primarily to decorate ILogger with some backward-compatible logging API's).

So here's my attempt to wrap castle's extended logger:

namespace Foo
{
    //classes will need to implement this interface (Logger prop will be injected by Windsor)
    public interface ILoggable
    {
        Foo.ILogger Logger { get; set; } //fails to resolve
        //Castle.Core.Logging.ILogger Logger { get; set; } //works, but I want clients to work with Foo.ILogger
    }

    public interface ILogger : Castle.Core.Logging.IExtendedLogger
    {
      //my custom log Methods
    }

    public class Logger : ExtendedLog4netLogger, ILogger
    {
        public Logger(log4net.ILog log, ExtendedLog4netFactory factory) : this(log.Logger, factory)
        {
        }

        public Logger(log4net.Core.ILogger logger, ExtendedLog4netFactory factory)
            : base(logger, factory)
        {
        }

        //my custom log Methods
    }

    public class ExtendedLoggerFactory : Castle.Services.Logging.Log4netIntegration.ExtendedLog4netFactory
    {
        public override IExtendedLogger Create(Type type)
        {
            var log = log4net.LogManager.GetLogger(type);
            return (ILogger)new Logger(log, this);
        }

        public override IExtendedLogger Create(String name)
        {
            var log = log4net.LogManager.GetLogger(name);
            return (ILogger)new Logger(log, this);
        }
    }

    public class Log4NetInstaller: IWindsorInstaller
    {
        public void Install(IWindsorContainer container, IConfigurationStore store)
        {
            container.AddFacility<LoggingFacility>(f =>
                f.UseLog4Net().WithAppConfig()
                .LogUsing<ExtendedLoggerFactory>()
            );

            //now register classes implementing ILoggable for property injection.
            container.Register(
                Classes.FromThisAssembly()
                    .BasedOn<ILoggable>());
        }
    }

} //namespace Foo

Unfortunately, the Foo.ILogger Logger property will not resolve (castle's ILogger Logger property works fine, of course). The following returns false in LoggerResolver :

        public bool CanResolve(CreationContext context, ISubDependencyResolver parentResolver, ComponentModel model, DependencyModel dependency)
        {
            return dependency.TargetType == typeof(ILogger) || dependency.TargetType == typeof(IExtendedLogger);
        }

This change will allow my types to resolve as hope/expected (and is a bit simple/more general as well):

        public bool CanResolve(CreationContext context, ISubDependencyResolver parentResolver, ComponentModel model, DependencyModel dependency)
        {
            //return dependency.TargetType == typeof(ILogger) || dependency.TargetType == typeof(IExtendedLogger);
            return typeof(Castle.Core.Logging.ILogger).IsAssignableFrom(dependency.TargetType);
        }

I'm still new to Windsor, so perhaps there's a better (non-invasive) way of making this work.

thanks!
--craig


Reply all
Reply to author
Forward
0 new messages