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