2009-08-24 58 views
5

我已经碰到了围绕着各种网站的这些问题中的一些问题,并且答案似乎是由l4n officianados转向log4net'是'的轻量级包装的值(不要你明白了吗?)以及类似的令人难以置信的事实。再次关于log4net和Unity IOC配置

但是,似乎用户所要求的(这是我的问题)是如何将log4net objet模型放入流利配置界面的registertype/registerinstance序列中。

这里的目标不是重新包装l4n,而是简单地抓住一个像样的参考,它不需要劫持流畅的流动,因为它是。

可怜的ejemplow,我想从LogManger.GetLogger方法中获得一个对ILog的配置实例的引用,并且尽早将它放入流畅流中,以便将其注入到我的下游对象的属性中。

所以响应一个不耐烦的建议,我试图在规范的方式创建的ILog的正常实例:

log4net.Config.XmlConfigurator.Configure(); 
static readonly log4Net.Ilog Log = LogManager.GetLogger(thatlongassemblyreflectionstuff); 

因此,这将是微不足道的(在毫不费力的真正意义上的),到现在补充一点参考到Unity容器并继续我美好的生活。

但是,RegisterInstance方法的签名需要'Type'而不是接口。

对于那些还没有通过log4net对象模型进行搜索的人来说,函数是正确的:l4n是一个'包装器',你不能为Log工具获得真正的'类型'的holt。

所以现在我必须测试。而且你知道这意味着什么,它可能需要一分钟,但更可能需要一个小时或四个小时(类似于'小时'和'四'的拼写在现实生活中从不巧合)。

然而,下面,减去约规范设置消隐部分,做过的工作:

container 
    .RegisterInstance("Logger", Log, new ContainerControlledLifetimeManager()) 
.RegisterType<IControllerContext, ControllerContext> 
(
    "CtlrCtx", 
    new ContainerControlledLifetimeManager(), 
    new InjectionConstructor(new ResolvedParameter<IMessageBuilder>("MsgBldr")), 
    new InjectionProperty("Log",new ResolvedParameter<ILog>("Logger")) 
); 

所以注入到我的marvy小上下文对象的属性为原单Log对象和Log对象哈希码是相同的。

但是......

,我通过它的接口暴露Context对象的Log属性,这意味着它可能不再是一个静态的对象所需的注射过程。而log4net ILog对象是否是静态的,似乎是决定它是否可序列化,并且可以在程序集之间进行mashalled而不会产生戏剧性的“运行时将变得不稳定”的警告(只对Matrix粉丝真正有意义)。

不鼓励,虽然没有阻止,但我使用了Resharper的'漂亮的属性与后台'并且设置后台字段为静态,而接口属性保持非静态。那么它建立和测试运行绿色。

所以我甚至做了重建,它的工作。所以也许当这起泡沫到集成测试时,我会偷偷走过log4net不是可序列化的崩溃。

所以,也许这将有助于

感谢

Stato

+0

将日志记录器作为实例变量是不正常的做法 - 它们通常是静态(即类)变量,无论如何都是以单例实现的。所以我不认为你从Unity容器中获取任何好处 - 你为什么需要? – 2009-10-09 19:42:39

+0

'为什么?'绝对是一个合理的问题。答案与单点配置有关。在任何地方使用任何记录器都会成为一个真正的配置负担,并且当涉及到乐趣时,“aint”部分的维护很重。 – 2011-02-09 23:48:57

回答

5

将在Unity 2帮助使用InjectionFactory? (见this question)。那么你的配置代码会是这个样子:

IUnityContainer container = new UnityContainer(); 
container.RegisterType<ILog>(new InjectionFactory(factory => LogManager.GetLogger())); 

然后您检索与通常的通话记录器来解决():

ILog logger = container.Resolve<ILog>(); 
logger.Log(Level.Debug, "Hello world"); 

您可能也有能够配置记录器的寿命也是ContainerControllerLifetimeManager,使它成为一个单例实例,但我还没有验证过。

+0

它看起来像log4net相关但对于为启动而构建的对象实例也很有用。谢谢。 – 2012-01-30 14:43:28

0
ILog logger = container.Resolve<ILog>(); 
logger.Log(Level.Debug, "Hello world"); 

确实有效。

但是,如果您在某个类上有记录器的属性,并且希望将此记录器实例注入到该对象中,则AFAICT不起作用。我想我可能会脱离目标,但我试图在新的上下文中重用记录器实例。这可能仅仅是可撤销的,所以我可能要放弃注入它,只是添加行

ILog logger = container.Resolve<ILog>(); 

到每一个班级,这给了我这个结果似乎只比在每一个类实例化它略有不同.. ..

我希望

private ILog Logger {get;set;} 

可能只是被注入,但似乎并没有在所有的工作,因为所有通过log4net的一切都是通过接口完成,具体记录器是躲在幕后与绿野仙踪。