依赖于log4net的记录器,并使用温莎城堡检索记录仪由主叫类型 [英] Dependency on Log4Net Logger and Retrieve Logger by Caller Type using Castle Windsor
问题描述
我身边有 log4net的
薄的包装,我尝试使用调用类的类型来从 log4net.LogManager <记录仪/ code>通过使用
Castle.Windsor
。
公共类Foo:IFoo的
{
私人只读ICommonLog _logger;
公共美孚(ICommonLog记录仪)
{
_logger =记录;
}
公共无效FooBar的()
{
_logger.Info(输入FooBar的方法);
}
}
公共类CommonLog:ICommonLog
{
私人只读log4net.ILog _logger;
公共CommonLog(类型loggerType)
{
_logger = log4net.LogManager.GetLogger(loggerType);
}
公共无效信息(字符串消息)
{
_logger.Info(message.Cleanse());
}
// ...
}
我已经尝试了本登记 Castle.Windsor
(2.5.1),我能得到正确的记录器富
。上午我错使用动态参数,对于这种情况?有没有更好的解决方案?
container.Register(Component.For&LT; ICommonLog&GT;()ImplementedBy(typeof运算(CommonLog))。
LifeStyle.Transient);
container.Register(Component.For&LT;的IFoo&GT;()ImplementedBy(typeof运算(富))。
LifeStyle.Transient.DynamicParameters(
(K,D)=&GT;
{
无功分量= k.Resolve&LT; ICommonLog&GT;(新{loggerType = typeof运算(富)});
D [记录仪] =组件;
返回R =&GT;
{
如果(分量!= NULL)
{
r.ReleaseComponent(组分);
}
};
})
);
编辑:我已经更新使用该解决方案 ISubDependencyResolver
:
公共类LoggerResolver:ISubDependencyResolver
{
私人只读的iKernel内核;
公共LoggerResolver(的iKernel内核)
{
this.kernel =内核;
}
公共BOOL CanResolve(CreationContext的背景下,
ISubDependencyResolver contextHandlerResolver,
ComponentModel模式,
DependencyModel依赖性)
{
返回dependency.TargetType == typeof运算(ICommonLog);
}
公共对象解析(CreationContext的背景下,
ISubDependencyResolver contextHandlerResolver,
ComponentModel模式,
DependencyModel依赖性)
{
如果(CanResolve(背景下,contextHandlerResolver,模型,依赖))
{
返回kernel.Resolve&其中; ICommonLog&GT;(新{loggerType = model.Implementation});
}
返回null;
}
}
报名方式:
container.Register(Component.For&LT; ICommonLog&GT;()ImplementedBy(typeof运算(CommonLog))
.LifeStyle.Transient);
container.Register(Component.For&LT;的IFoo()ImplementedBy(typeof运算(富))
.LifeStyle.Transient);
container.Kernel.Resolver.AddSubResolver(新LoggerResolver(container.Kernel));
您并不需要注册CommonLog。你分依赖解析器可以新一轮上涨给你。
<$p$p><$c$c>container.Register(Component.For<IFoo>().ImplementedBy<Foo>().LifeStyle.Transient); container.Kernel.Resolver.AddSubResolver(新LoggerResolver(container.Kernel)); 公共类LoggerResolver:ISubDependencyResolver { ... 公共对象解析(CreationContext背景下,ISubDependencyResolver contextHandlerResolver,ComponentModel模型,DependencyModel依赖) { //无需能够解决,温莎会为你做这个 返回新CommonLog(model.Implementation); } }
记录仪提供的编辑为例
<$p$p><$c$c>container.Register(Component.For<ILoggerProvider>().ImplementedBy<Log4NetLoggerProvider &GT;()LifeStyle.Transient); 公共接口ICommonLoggerProvider { ICommonLog GetLogger(类型类型); } 公共类Log4NetLoggerProvider:ICommonLoggerProvider { 公共ICommonLog GetLogger(类型类型) { 返回新Log4NetLogger(类型); } } 公共类LoggerResolver:ISubDependencyResolver { ... 公共对象解析(CreationContext背景下,ISubDependencyResolver contextHandlerResolver,Castle.Core.ComponentModel模型,DependencyModel依赖) { 返回kernel.Resolve&LT; ICommonLoggerProvider&GT;()GetLogger(model.Implementation); } }I have a thin wrapper around log4net
and I am trying to use the type of the calling class to get a logger from log4net.LogManager
by using Castle.Windsor
.
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());
}
// ...
}
I have tried this registration in Castle.Windsor
(2.5.1) and I am able to get the correct logger for Foo
. Am I mis-using dynamic parameters for this scenario? Is there a more elegant solution?
container.Register(Component.For<ICommonLog>().ImplementedBy(typeof(CommonLog)).
LifeStyle.Transient);
container.Register(Component.For<IFoo>().ImplementedBy(typeof(Foo)).
LifeStyle.Transient.DynamicParameters(
(k, d) =>
{
var component = k.Resolve<ICommonLog>(new {loggerType = typeof (Foo)});
d["logger"] = component;
return r =>
{
if (component != null)
{
r.ReleaseComponent(component);
}
};
})
);
Edit: I've updated the solution using 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<ICommonLog>(new {loggerType = model.Implementation});
}
return null;
}
}
Registration:
container.Register(Component.For<ICommonLog>().ImplementedBy(typeof(CommonLog))
.LifeStyle.Transient);
container.Register(Component.For<IFoo().ImplementedBy(typeof(Foo))
.LifeStyle.Transient);
container.Kernel.Resolver.AddSubResolver(new LoggerResolver(container.Kernel));
You do not need to register CommonLog. Your sub dependency resolver can new one up for you.
container.Register(Component.For<IFoo>().ImplementedBy<Foo>().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);
}
}
EDIT Example of a logger provider
container.Register(Component.For<ILoggerProvider>().ImplementedBy<Log4NetLoggerProvider >().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<ICommonLoggerProvider>().GetLogger( model.Implementation );
}
}
这篇关于依赖于log4net的记录器,并使用温莎城堡检索记录仪由主叫类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!