2009-08-24 60 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的一切都是通過接口完成,具體記錄器是躲在幕後與綠野仙蹤。