最近事情比較多,有預研的,有目前正在研發的,都是很需要時間的工作,所以導致這周只寫了兩篇Orchard系列的文章,這邊不能保證后期會很頻繁的更新該系列,但我會寫完這整個系列,包括后面會把正在研發的東西跟大家一起分享(架構、思想上的分享)。
今天我們來看一看Orchard中的Logging Component。
日志在Orchard中的使用
像這樣的代碼大家在Orchard中肯定經常見到,那么NullLogger.Instance是什么?大量使用依賴注入的Orchard會把真正的日志記錄器放在一個靜態變量里面嗎?答案肯定是否定的,我們來看一看NullLogger。
NullLogger明顯是空的,那么ILogger到底是誰?怎么進入到服務中的?
LoggingModule
不知道大家對“Orchard 刨析:前奏曲”中的CachingModule還有沒有印象,Orchard用了類似的機制,只不過這一次把構造函數注入變成了屬性注入。
在Load方法我們可以看到Orchard把一個CreateLogger委托(方法)注冊成為了一個ILogger接口,也就是在服務需要(請求)類型為ILogger的服務時候會執行這個委托,這個委托會返回一個ILogger實例。
我們來看一看這個神奇的CreateLogger委托。
方法比較簡單,解析一個ILoggerFactory並通過LoggerFactory為請求服務的類型創建出一個Logger。
對於ILogger由誰創建的疑惑我們揭開了,但是怎么確保它是以屬性輸入的方式被注入進來的?下面我們接着看。
這個方法比較簡單,在AttachToComponentRegistration方法中調用BuildLoggerInjectors方法生成注入的動作,並在服務被激活(服務實例創建完成后)之后執行這些委托。
BuildLoggerInjectors方法稍顯復雜些,但對經常使用反射的人來說很快就能看得明白。
主要的流程如下:
1.獲取服務類型中所有符合約定的屬性(具有Set方法、必須是Public、是一個實例、屬性類型是ILogger、不具備索引參數)
2.遍歷這些屬性
3.解析ILogger服務(實則調用CreateLogger)
4.把ILogger的實例設置到該屬性上。
到這邊ILogger是怎么被創建的我們已經明白了,那么為什么需要NullLogger.Instance呢?
為什么需要NullLogger
其實原因很簡單,日志組件不一定是必要的,也就是說在框架運行起來的時候壓根我們就沒有日志組件,如果沒有日志組件那么在解析ILogger的時候肯定是失敗的(ILogger為null),這時候如果我們在服務中使用ILogger的實例肯定是未引用對象到實例,否則就需要判斷ILogger是否為null在進行日志記錄,豈不麻煩。所以NullLogger.Instance的用意就在解決這個問題。
ILogger是誰?
以上我們弄明白了ILogger怎么來的下面我們來看看ILogger是誰?
首先我們來看一幅圖:
ILoggerFactory和ILogger這兩個接口在上面我們已經知道在哪里被使用了,下面我們來看看Logging組件的具體實現部分。
不知道大家一開始看這些有沒有疑惑,為什么使用了Castle Logging還要使用Log4net呢?
我們知道.net下的日志組件非常多,如:Log4net、NLog等。每一套日志組件都有部分自己特有的API,但實現的功能都大同小異,Orchard為了使API統一化而引入Castle Logging,Castle Logging並不是一個可用的日志組件,而是一套抽象的日志API。
也就是說日志的記錄怎么變化只要可以適配Castle Logging就可以直接與框架集成。
CastleLoggerFactory工廠中通過Castle Logging的ILoggerFactory創建一個CastleLogger的實例。
那么具體的擴展就在Castle的ILoggerFactory中了,回顧剛才的LoggingModule:
可以發現框架默認把OrchardLog4netFactory作為了Castle的ILoggerFactory,並且上面有一行注釋,大致意思是:默認使用委托果園的日志記錄器到Castle的日志記錄器工廠。
到這里Logging Component的整體我們都差不多了解了。OrchardLog4netFactory和OrchardLog4netLogger就不深入的,比較簡單,如果閱讀還是顯得比較吃力可以去Log4net官網上面去看看。
OrchardFileAppender
該類並沒有在編碼中出現,而是Log4net提供的一種可擴展的方式,出現在log4net.config中。具體的可以去Log4net官網上了解。
寫在最后
不保證很頻繁的更新本系列但保證本系列肯定會寫完,最近在對一個較老的組件(系統?不知道怎么命名更貼切)以新的架構新的思想和自己的方式重新編碼實現,待第一版出來之后會跟大家做分享(架構、思想上的分享)。
為了本系列的讀者有更好的交流環境提供QQ群一個:299744835











