5

我已经在各个站点上遇到了一些这样的问题,并且答案似乎是由 l4n 官员针对 log4net“是”的轻量级包装器的价值(你不明白吗?)和类似的想法-令人难以置信的事实。

然而,似乎用户所要求的(这是我的问题)是如何将 log4net 对象模型适合流利的配置界面中的 registertype/registerinstance 序列。

这里的目标不是重新包装 l4n,而只是为了获取一个体面的引用,它不需要劫持流畅的流,因为它是。

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

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

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

因此,现在将这个引用添加到 Unity 容器并继续我的美好生活似乎是微不足道的(在真正意义上的轻松)。

但是,RegisterInstance 方法的签名需要“类型”而不是接口。

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

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

但是,以下内容(减去关于规范设置的省略部分)确实有效:

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 不是可序列化的崩溃。

所以也许这会有所帮助

谢谢

斯塔托

4

2 回答 2

5

在 Unity 2 中使用 InjectionFactory 会有帮助吗?(见这个问题)。然后您的配置代码将如下所示:

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,使其成为单例实例,但我尚未验证。

于 2011-02-07T06:00:31.313 回答
0
ILog logger = container.Resolve<ILog>();
logger.Log(Level.Debug, "Hello world");

确实有效。

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

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

到每个班级,这给我的结果似乎与在每个班级中实例化它略有不同......

我希望那

private ILog Logger {get;set;} 

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

于 2011-06-09T22:44:09.423 回答