Share via


擴充發送器

發送器負責從基礎通道提取傳入訊息,將訊息轉譯成應用程式程式碼中的方法叫用,然後將結果傳回給呼叫者。 發送器擴充可讓您修改這個處理。 您可以實作可檢查或修改訊息或參數之內容的訊息或參數偵測器。 您可以變更訊息路由傳送到作業的方式,或提供其他特定功能。

此主題描述如何在 Windows Communication Foundation (WCF) 服務應用程式中使用 DispatchRuntimeDispatchOperation 類別來修改發送器的預設執行行為,或者攔截或修改在從通道層為其進行傳送或擷取之前或之後的訊息、參數或傳回值。 如需對等用戶端執行階段訊息處理的詳細資訊,請參閱擴充用戶端。 若要了解 IExtensibleObject<T> 型別存取各種執行階段自訂物件之間的共用狀態時所扮演的角色,請參閱可擴充物件

發送器

服務模型層會在開發人員的程式設計模型與一般稱為通道層的基礎訊息交換之間執行轉換。 在 WCF 中,通道發送器和端點發送器 (分別為 ChannelDispatcherEndpointDispatcher) 是負責接受新通道、接收訊息、作業分派和叫用以及回應處理的服務元件。 發送器物件是指接收物件,但是雙工服務中的回呼合約實作也會公開其發送器物件,以進行檢查、修改或擴充。

通道發送器和隨附的 IChannelListener 會從基礎通道中提取訊息,並將訊息傳遞至個別的端點發送器。 每個端點發送器都有一個 DispatchRuntime,可將訊息傳送至適當的 DispatchOperation (負責呼叫可實作作業的方法)。 過程中需要各種選擇性及必要的延伸類別。 本主題說明這些部分如何互相配合,以及如何修改屬性並插入您自己的程式碼以擴充基礎功能。

發送器屬性與修改的自訂物件可透過服務、端點、合約,或作業行為物件來插入。 本主題未說明這些行為的用法。 如需用來插入發送器修改的型別詳細資訊,請參閱使用行為來設定與擴充執行階段

下圖提供服務中架構項目的高階檢視。

The dispatch runtime architecture

通道發送器

ChannelDispatcher 物件是建立用來將服務執行個體與位於特定 URI (稱為接聽 URI) 的 IChannelListener 產生關聯。 每個 ServiceHost 物件都可以擁有許多 ChannelDispatcher 物件,而其中每一個物件只會與一個接聽項和接聽 URI 產生關聯。 當訊息抵達時,ChannelDispatcher 會查詢每個關聯的 EndpointDispatcher 物件來判定該端點是否可以接受此訊息,然後將該訊息傳遞至可以接受的端點。

所有控制通道工作階段之存留期及行為的屬性都可以用來檢查或修改 ChannelDispatcher 物件, 這些屬性包括自訂通道初始設定式、通道接聽項、主機與關聯的 InstanceContext 等等。

端點發送器

當訊息的目的端位址符合 EndpointDispatcher,而且訊息動作符合 ChannelDispatcher 屬性時,AddressFilter 物件就會負責處理來自 ContractFilter 的訊息。 如果有兩個 EndpointDispatcher 物件可以接受訊息,FilterPriority 屬性值會決定使用較高優先順序的端點。

使用 EndpointDispatcher 即可取得兩個主要的服務模型擴充點 (DispatchRuntimeDispatchOperation 類別),以便您用來自訂發送器的處理。 DispatchRuntime 類別可讓使用者在合約範圍內 (亦即針對合約內的所有訊息) 攔截與擴充發送器, DispatchOperation 類別則可讓使用者在作業範圍內 (亦即針對作業內的所有訊息) 攔截與擴充發送器。

案例

發送器會因為下列某些原因而需要擴充:

  • 自訂訊息驗證。 使用者可以強制訊息對特定結構描述有效, 實作訊息攔截器介面即可達到這個目的。 如需範例,請參閱訊息偵測器

  • 自訂訊息記錄。 使用者可以檢查和記錄某個流經端點的應用程式訊息集合, 使用訊息攔截器介面也可以完成這個動作。

  • 自訂訊息轉換。 使用者可以將特定轉換套用至執行階段中的訊息 (例如用來進行版本控制), 使用訊息攔截器介面同樣可以完成這個動作。

  • 自訂資料模型。 使用者可以擁有 WCF 預設支援以外的資料序列化模型 (也就是 System.Runtime.Serialization.DataContractSerializerSystem.Xml.Serialization.XmlSerializer 和原始訊息)。 實作訊息格式器介面即可達到這個目的。 如需範例,請參閱作業格式器和作業選取器

  • 自訂參數驗證。 使用者可以強制型別參數都是有效的參數 (相對於 XML), 使用參數偵測器介面即可達到這個目的。

  • 自訂作業分派。 使用者可以針對動作以外的項目 (例如主體項目或自訂訊息屬性) 實作分派, 使用 IDispatchOperationSelector 介面即可達到這個目的。 如需範例,請參閱作業格式器和作業選取器

  • 物件共用。 使用者可以共用執行個體,而不為每個呼叫分配一個新的執行個體, 使用執行個體提供者介面即可實作這個動作。 如需範例,請參閱共用

  • 執行個體租用。 使用者可以實作執行個體存留期的租用模式,方法與實作 .NET Framework 遠端處理的租用模式類似。 使用執行個體內容存留期介面即可達到這個目的。

  • 自訂錯誤處理。 使用者可以控制如何同時處理本機錯誤,以及如何將錯誤傳回用戶端。 使用 IErrorHandler 介面即可實作這個動作。

  • 自訂授權行為。 使用者可以擴充「合約」或「作業」執行階段片段,並根據訊息中存在的權杖新增安全性檢查,以實作自訂存取控制。 使用訊息攔截器或參數攔截器介面即可達到這個目的。 如需範例,請參閱安全性擴充性

    警告

    由於改變安全性屬性有可能會降低 WCF 應用程式的安全性,所以強烈建議您小心進行有關安全性的修改,而且在部署之前必須先完整測試。

  • 自訂 WCF 執行階段驗證器。 您可以安裝會檢查服務、合約與繫結的自訂驗證器,以強制執行有關 WCF 應用程式的企業層級原則。 (例如,請參閱如何:鎖定企業的端點)。

使用 DispatchRuntime 類別

使用 DispatchRuntime 類別即可修改服務或個別端點的預設行為,或是將實作自訂修改的物件插入下列其中一個或所有服務處理序 (或雙工用戶端情況下的用戶端處理序):

  • 將傳入訊息轉換成物件,並且在針對服務物件叫用方法時釋放這些物件。

  • 將回應叫用服務作業時收到的物件轉換成傳出訊息。

即使無法辨識訊息,DispatchRuntime 仍可讓您為特定合約上的所有訊息攔截及擴充通道或端點發送器。 當抵達的訊息不符合在合約中宣告的任何訊息時,該訊息會被分派至由 UnhandledDispatchOperation 屬性傳回的作業。 若要針對特定作業在所有訊息上進行攔截或擴充,請參閱 DispatchOperation 類別。

發送器擴充性的四個主要區域是由 DispatchRuntime 類別所公開:

  1. 通道元件會使用 DispatchRuntime 的屬性以及由 ChannelDispatcher 屬性傳回之相關通道發送器的屬性,以自訂通道發送器如何接受及關閉通道。 這個分類包括 ChannelInitializersInputSessionShutdownHandlers 屬性。

  2. 訊息元件會針對所處理的各個訊息進行自訂。 這個分類包括 MessageInspectorsOperationSelectorOperationsErrorHandlers 屬性。

  3. 執行個體元件會自訂服務類型執行個體的建立、存留期和處置。 如需服務物件存留期的詳細資訊,請參閱 InstanceContextMode 屬性。 這個分類包括 InstanceContextInitializersInstanceProvider 屬性。

  4. 安全性相關的元件可以使用下列屬性:

一般來說,自訂延伸物件會指派給 DispatchRuntime 屬性,或由服務行為 (實作 IServiceBehavior 的物件)、合約行為 (實作 IContractBehavior 的物件) 或端點行為 (實作 IEndpointBehavior 的物件) 插入集合中。 接著,安裝行為物件會透過程式設計的方式或實作自訂 BehaviorExtensionElement 物件的方式新增至適當的行為集合,讓該行為可以透過應用程式組態檔插入。

雙工用戶端 (實作由雙工服務指定之回呼合約的用戶端) 也有一個 DispatchRuntime 物件,您可以使用 CallbackDispatchRuntime 屬性來存取該物件。

使用 DispatchOperation 類別

DispatchOperation 類別是進行執行階段修改的位置,以及範圍僅限一項服務作業之自訂延伸的插入點。 若要修改合約中所有訊息的服務執行階段行為,請使用 DispatchRuntime 類別。

使用自訂服務行為物件即可安裝 DispatchOperation 修改。

您可以使用 Operations 屬性找出表示特定服務作業的 DispatchOperation 物件。

下列屬性控制作業層級的執行階段執行:

另請參閱