到目前為止,應該對於Autofac的使用有了基本的了解。在上一篇用了一個簡單的Log服務來說明Autofac如何和Mvc結合。
Log屬於任何一個系統必須有的服務,因此在這一篇,我們打造真的Log服務。
建立的流程
基本上會和我們在上一篇打造那個服務一樣,我們會:
- 定義Log所會擁有的Service(interface)
- 實作一個我們框架會用的Log Component
- 註冊到ContainerBuilder
定義Log擁有的Service
基本上,一般的log都有一些log層級,可以讓我們寫log的時候區分那些屬於錯誤(Error),和那些是偵錯(Debug)時候看的。因此,有以下幾個層級:
- Trace
- Debug
- Info
- Warn
- Error
- Fatal
層級定義完成之後,我們要決定每一個層級要有那些寫log的方法:
- (string message) - 只是把message輸出
- (object outpuObject) - 把物件資訊印出來
- (string message, params object[] args) - message是訊息,可以用string format一樣的placeholder,而args是placeholder的值
- (string message, object outputObject) - 要輸出的訊息和把物件資訊印出來
最後,由於有6個log層級和每一個層級都有4個方法,總共有24個需要定義,這邊我只定義某一個層級的4個方法,剩下都會一樣:
定義ILog的實作
有了Service定義好了之後,我們就要來決定我們要如何實作ILog。
第一件事情是決定自己要使用的Log Framework。比較出名的有NLog和Log4Net。我這邊會選擇使用NLog。
NLog
- 官網:http://nlog-project.org/
- Wiki:https://github.com/nlog/nlog/wiki
- 文件:http://nlog-project.org/documentation
- Nuget 指令:Install-Package NLog
設定一些注入用的參數
有用過Log Framework就會知道,通常我們會想要知道,是哪一個Class寫出了某一筆的log,因此在建立Log的class的時候能夠傳入要用這個log的Class 名稱。
我們也希望我們的Log Framework有這個功能,因此我們需要先定義出來,好讓Autofac能夠幫忙注入Class名稱。
我們透過的方式會是用Constructor來傳遞我們class的名稱。
定義interface的實作
再來我們要實際實作interface定義的24個方法。
有兩個部分需要特別處理:
- 怎麼把物件資訊dump出來
- log framework通常都能夠判斷某個層級是否需要開放輸出
針對第一個,我將會使用Json.Net
來把物件資訊dump出來。這個有好有懷,好處是不用寫複雜的邏輯來把物件印出來,而且顯示的樣式是熟悉的Json格式。而壞處是我們多了一個json .Net的 dependency。
Json .Net
屬於必裝型的套件。主要工作室Class <=> Json之間互相的轉換。效能上面比內建的快(根據他們自己的評測)
- 官網:https://json.codeplex.com/
- 文件:http://james.newtonking.com/json/help/index.html
- Nuget指令:Install-Package Newtonsoft.Json
針對第二個,我們每個層級的四個方法都用統一的一個方法做輸出,這樣就會做判斷需不需要實際呼叫:
上面顯示了Trace層級的方法實際定義,其他幾個層級的實作會一樣。
在ContainerBuilder註冊
在這邊有一點是之前沒有講過的,我們的NlogLogger裡面是沒有無參數的建構子。而我們接受的參數只是一個string的參數叫做name。那麼,照著我們目前所了解的註冊裡面,是沒有辦法解決這個問題。不過,Autofac當然有想到這種情況,因此我們這邊乘著這個機會介紹一下。
我們先了解一下,string name
的參數是要傳入什麼?
我們之前講過,log framework都有一個參數是記錄寫這個log的class 名稱。因此我們這個參數代表就是這個要用NlogLogger的class 名稱。
那要如何注入這個class名稱呢?在Autofac裡面有Module可以讓我們設定特殊的註冊邏輯。同時,在Module裡面有提供event讓我們可以再Autofac實例化component的時候,做一些事情。因此我們可以透過這個方法來注入我們class的名稱。
建立NlogModule
建立一個Autofac的Module需要建立一個Class繼承Autofac.Module
。
我們這邊會複寫兩個method:
Load
- Module註冊第一個會執行的方法。這邊可以設定我們的NlogLogger將會作為ILog service的Component。AttachToComponentRegistration
這邊就是讓我們可以註冊一些在建立時候的事件
這一段的程式碼是參考網路上面的資料,因此有些註解是英文。
從上面可以看到,在AttachToComponentRegistration
我們註冊了兩個事件,一個是用來處理Constructor的時候注入參數,另外一個是用Property的方式注入。
我們實作的版本是沒有允許用Property的方式注入,不過保留這個方法僅供參考。
接下來我們看一下,Constructor注入的方法是如何寫的:
最後,看一下如果用Property Inject的話是如何實現
到這邊,我們的Autofac.Module就建立好了。
註冊Autofac.Module
之前註冊的時候也沒有提到如何註冊Autofac.Module,這一次一起介紹。
其他註冊的部分我們就不看了,就只看註冊Module的部分:
這樣註冊就完成了,至於使用,就和上一篇介紹那樣,在要用到ILog的Controller裡面,把Constructor有個參數接受ILog形態的參數即可。
結語
透過這一篇,我們就知道了如何建立一個Log的功能,並且如何作為我們第一個框架的服務。
在下一篇開始,將會介紹再用Mvc開發的時候,最常用到的ViewModel概念和為什麼要使用ViewModel。
有關於程式碼的部分,稍後會補上整個專案,以供參考。