上篇回顧思考這個問題的時候,是否想到了在web上大顯身手的mvc模式哪?想一下mvc是如何判斷應該呼叫那個controller的,當然當然是routetable。
那麼我們為什麼不也作乙個路由表哪?
打造路由表——尋找url的等價物開始打造我們自己的路由表之前,需要想明白一件事情,wcf裡面的路由的url怎麼取,事實上,wcf的每個操作都有自己的action,因此,完全可以用action來作為wcf中url的等價物。
那麼,怎麼在wcf中抓取出當前操作的action哪?
其實,相當的簡單,只需要這樣一句就可以了:
string action = operationcontext.current.incomingmessageheaders.action;
有了action,這個url的等價物之後,我們需要做的就是決定如何定義乙個路由表,這個字串簡單,變成乙個可以執行的操作。
打造路由表——思考路由策略因為是自己打造路由,所以,很多時候可以跳出現有的mvc之類的框架的思維定式,尋找乙個真正想要的策略(即使不是什麼最佳策略,也無關緊要)。
對於任何乙個wcf的操作來說,總是可以想象到下面這幾步的:
其中,各種未知操作可能也會出現管道/過濾器式(pipe/filter)的處理,前一步做完再做下一步。因此,我們的路由表最好能支援鏈式處理。
說到這裡,是不是想到了什麼?
至少我在第一時間想到的是:設計模式——責任鏈模式。
打造路由表——基於責任鏈的路由表既然確定了要基於責任鏈,那麼首先來準備責任鏈的基礎型別:
public
inte***ce ioperationhandler
object request
object response
void handle();
}
打造路由表——路由到原始處理在打造別的handler之前,先寫乙個原始的wcf的處理
internal
sealed
class rawhandler
: ioperationhandler
public
object request
public
object response
private
readonly ioperationinvoker m_raw;
public rawhandler(object instance, ioperationinvoker raw)
public
override
void handle()
, out outputs);
}}
有了這個rawhandler,就可以打造出:
public
abstract
class handle***ctory
}private
static handle***ctory m_current = m_default;
public
static handle***ctory current
set
}public
abstract ioperationhandler createhandlerchains(rawhandler raw);
}internal
sealed
class defaulthandle***ctory
: handle***ctory
}
public
object invoke(object instance, object inputs, out
object outputs)
到目前為止,wcf服務就有可以正常的跑起來了,當然目前沒有更改任何wcf的行為,而僅僅是繞了一圈,把服務裡面加了個攔截和路由,並且路由總是直接呼叫服務原來的**實現。
感到很沮喪?別急,雖然到這裡寫了一大堆類,並且沒有更改任何的wcf的預設行為,但是,已經成功的加入了乙個可以更改wcf行為的注入點:createhandlerchains方法
通過這個方法,我們可以隨時新增handler,來修改wcf的行為。
打造路由表——硬編碼的路由表在思考如何動態配置之前,不妨先從硬編碼開始。所以寫乙個簡單的hardcodehandle***ctory:
public
class hardcodehandle***ctory
: handle***ctory
}public
void add(funccreator, string actionpattern));}
public
override ioperationhandler createhandlerchains(rawhandler raw)
}return handler;
}}
通過這個簡單的factory,可以很簡單的通過新增handler,作用於那些action符合pattern的操作。
為了方便演示,先定義乙個簡單的handler:
public
abstract
class operationhandlerbase
: ioperationhandler
public
abstract
void handle();
public
object request
set}
public
object response
set}
}public
class loghandler
: operationhandlerbase
", operationcontext.current.incomingmessageheaders.action);
// this handler can handle nothing.
//if (false)
// return;
//else
if (next != null)
else
not implemented.", operationcontext.current.incomingmessageheaders.action);
throw
new faultexception("not implemented.");
}trace.traceinformation("end action:", operationcontext.current.incomingmessageheaders.action);
}}
然後再把這個handler註冊到工廠中,例如:
hardcodehandle***ctory f = new hardcodehandle***ctory();
f.add(handler => new loghandler , "\\s");
handle***ctory.current = f;
這樣,所有有controller這個特性的wcf操作都會在開始和正常結束的時候輸出2行日誌(因為正則\s可以匹配和action,如果需要選擇性的注入,可以修改正則)。
當然,因為loghandler本身並不能處理掉任何的請求,因此,在責任鏈中的它必須把請求傳送給下乙個處理者(如果沒有下乙個處理者,那就是有問題的責任鏈,因此直接拋錯)。
但是在某些handler中(例如負責引數檢查的handler),如果發現引數有問題,將可以直接將請求變成已經處理,從而短路後面的處理。
打造路由表——思考和下篇預告前面一節,已經可以簡單實現hardcode的路由功能,然後可以思考一下如何通過配置的形式來更改路由表。
思考一下路由的要素:
ldap服務端配置
ldap lightweight directory access protocol 輕量目錄訪問協議.它以樹狀的層次結構來儲存資料,是一種特殊的資料庫系統.ldap往往用於在乙個大的區域網下進行統一的賬號管理 下面進行ldap的服務端配置 1.安裝ldap所需元件 yum install ldap...
SVN服務端配置
一 建立乙個專案 建立版本倉庫,dos環境基本語法 svnadmin creae shop 資料夾路徑 shop倉庫 如果shop倉庫配置成功,那麼shop資料夾會顯示以下以下目錄結構 4.進行伺服器端監管 首先看下php監管 apache http localhost或 ip位址 訪問到htdoc...
cvsnt服務端配置
由於專案組需要,在windows下自己動手配置了下cvs 服務端 本人使用cvsnt 2.5.03.2151 一路next。1,選擇 程式 cvsnt cvsnt control panel 增加乙個 repository 網上說,增加倉儲時目錄要選擇ntfs檔案格式的磁碟,本人沒有試過在 fat3...