使用Castle Windsor通过调用者类型依赖Log4Net Logger和检索记录器

我在log4net周围有一个瘦的包装器,我试图使用类型的调用类通过使用Castle.Windsorlog4net.LogManager获取一个记录器。

 public class Foo: IFoo { private readonly ICommonLog _logger; public Foo(ICommonLog logger) { _logger = logger; } public void FooBar() { _logger.Info("Enter FooBar Method"); } } public class CommonLog : ICommonLog { private readonly log4net.ILog _logger; public CommonLog(Type loggerType) { _logger = log4net.LogManager.GetLogger(loggerType); } public void Info(string message) { _logger.Info(message.Cleanse()); } // ... } 

我在Castle.Windsor (2.5.1)中尝试过这个注册,我能够为Foo获得正确的记录器。 我是否误用了这种情况的动态参数? 有更优雅的解决方案吗?

 container.Register(Component.For().ImplementedBy(typeof(CommonLog)). LifeStyle.Transient); container.Register(Component.For().ImplementedBy(typeof(Foo)). LifeStyle.Transient.DynamicParameters( (k, d) => { var component = k.Resolve(new {loggerType = typeof (Foo)}); d["logger"] = component; return r => { if (component != null) { r.ReleaseComponent(component); } }; }) ); 

编辑:我已使用ISubDependencyResolver更新了解决方案:

 public class LoggerResolver : ISubDependencyResolver { private readonly IKernel kernel; public LoggerResolver(IKernel kernel) { this.kernel = kernel; } public bool CanResolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency) { return dependency.TargetType == typeof (ICommonLog); } public object Resolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency) { if (CanResolve(context, contextHandlerResolver, model, dependency)) { return kernel.Resolve(new {loggerType = model.Implementation}); } return null; } } 

注册:

 container.Register(Component.For().ImplementedBy(typeof(CommonLog)) .LifeStyle.Transient); container.Register(Component.For<IFoo().ImplementedBy(typeof(Foo)) .LifeStyle.Transient); container.Kernel.Resolver.AddSubResolver(new LoggerResolver(container.Kernel)); 

您无需注册CommonLog。 您的子依赖解析器可以为您提供新的依赖解析器。

 container.Register(Component.For().ImplementedBy().LifeStyle.Transient); container.Kernel.Resolver.AddSubResolver(new LoggerResolver(container.Kernel)); public class LoggerResolver : ISubDependencyResolver { ... public object Resolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency) { //No need to can resolve, Windsor will do this for you return new CommonLog(model.Implementation); } } 

编辑记录器提供程序的示例

 container.Register(Component.For().ImplementedBy().LifeStyle.Transient); public interface ICommonLoggerProvider { ICommonLog GetLogger( Type type ); } public class Log4NetLoggerProvider : ICommonLoggerProvider { public ICommonLog GetLogger(Type type) { return new Log4NetLogger(type); } } public class LoggerResolver : ISubDependencyResolver { ... public object Resolve( CreationContext context, ISubDependencyResolver contextHandlerResolver, Castle.Core.ComponentModel model, DependencyModel dependency ) { return kernel.Resolve().GetLogger( model.Implementation ); } }