再次关于log4net和Unity IOC配置

时间:2009-08-24 07:03:59

标签: configuration log4net unity-container

我已经碰到了围绕各个网站的一些问题,答案似乎是由l4n officianados转向了log4net'是'的轻量级包装器的价值(你不明白吗?)和类似的令人难以置信的事实。

然而,似乎用户要求的(这是我的问题)是如何使log4net objet模型适应fluent配置界面中的registertype / registerinstance序列。

这里的目标不是重新包装l4n,而是简单地抓住一个不需要劫持流畅流量的体面参考。

糟糕的ejemplow,我想从LogManger.GetLogger方法获取对已配置的ILog实例的引用,并将其尽早放入流畅的流中,以将其注入我的下游对象的属性中。

因此,为了回应一个不耐烦的建议,我尝试以规范的方式创建了一个正常的ILog实例:

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

所以现在将这个引用添加到Unity容器并继续我的美好生活似乎是微不足道的(在真正意义上毫不费力)。

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

对于那些没有搜索过log4net对象模型的人来说,afficiananderos是正确的:l4n是一个“包装器”,你无法得到Log thingie的实际“类型”。

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

然而,以下内容,减去了关于规范设置的省略部分,确实有效:

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"))
);

因此,原始Log对象的哈希码和注入到我的小型Context对象的属性中的Log对象是相同的。

...然而

注入过程要求我通过其接口公开Context对象的Log属性,这意味着它不再是静态对象。并且log4net ILog对象是否是静态的似乎是决定它是否可序列化并且可以在程序集之间进行编组而没有戏剧性的“运行时将变得不稳定”警告(这对于Matrix粉丝来说真正有意义)。

气馁,尽管没有阻止,我使用Resharper的漂亮'来支持具有支持字段的属性'并将支持字段设置为静态,而Interface属性保持非静态。它建成了,测试运行绿色。

所以我甚至进行了重建并且有效。所以也许当这个泡沫达到集成测试时,我会偷偷溜过log4net,这不是可序列化的崩溃。

所以也许这会有所帮助

由于

Stato

2 个答案:

答案 0 :(得分:5)

使用Unity 2中的InjectionFactory会有帮助吗? (见this question)。然后你的配置代码看起来像这样:

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

然后通过调用Resolve()来检索记录器:

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

您也可以将记录器的生命周期配置为ContainerControllerLifetimeManager,使其成为单例实例,但我还没有验证过。

答案 1 :(得分:0)

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

确实有用。

但是,如果您有一个类的记录器属性,并且想要将此记录器实例注入其中,那将无法使用AFAICT。我想我可能不在目标,但我试图在新的上下文中重用logger实例。这可能只是可以撤销,所以我可能不得不放弃注入它并只添加行

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

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

我希望

private ILog Logger {get;set;} 

可能只是被注入,但这似乎根本不起作用,因为所有通过log4net一切都是通过接口完成的,具体的记录器隐藏在绿野仙踪的幕后。