WCF 強大的擴展架構讓開發者能在訊息處理管線的關鍵節點注入自定義邏輯。行為擴展 是最常用的擴展點,本文系統梳理四大行為類型、核心攔截介面、配置與屬性註冊方式,並提供實戰代碼範例。
定義於 System.ServiceModel.Dispatcher 命名空間,分為參數檢查、訊息檢查、操作調用器三類:
| 介面 | 作用端 | 核心方法 | 用途 |
|---|---|---|---|
IParameterInspector | 服務端/客戶端 | BeforeCall/AfterCall | 方法參數驗證、日誌、返回值處理 |
IDispatchMessageInspector | 服務端 | AfterReceiveRequest/BeforeSendReply | 服務端訊息攔截(請求/回覆) |
IClientMessageInspector | 客戶端 | BeforeSendRequest/AfterReceiveReply | 客戶端訊息攔截(請求/回覆) |
IOperationInvoker | 服務端 | Invoke 等 | 自定義操作調用邏輯(如異步包裝、事務) |
注意: IDispatchMessageInspector 與 IClientMessageInspector 方法順序相反,前者先 AfterReceiveRequest 後 BeforeSendReply,後者先 BeforeSendRequest 後 AfterReceiveReply。
| 行為類型 | 介面 | 作用範圍 | 適用方法 |
|---|---|---|---|
| 服務行為 | IServiceBehavior | 整個服務 (ServiceHost) | AddBindingParameters, ApplyDispatchBehavior |
| 端點行為 | IEndpointBehavior | 特定端點 | AddBindingParameters, ApplyClientBehavior, ApplyDispatchBehavior |
| 契約行為 | IContractBehavior | 特定契約 | AddBindingParameters, ApplyClientBehavior, ApplyDispatchBehavior |
| 操作行為 | IOperationBehavior | 特定操作 | AddBindingParameters, ApplyClientBehavior, ApplyDispatchBehavior, Validate |
| 行為類型 | 屬性註冊 | 配置檔註冊 | ServiceDescription 程式化註冊 |
|---|---|---|---|
| 服務行為 | ✓ | ✓ | ✓ |
| 端點行為 | ✗ | ✓ | ✓ |
| 契約行為 | ✓ | ✗ | ✓ |
| 操作行為 | ✓ | ✗ | ✓ |
public class CalculatorParameterInspector : IParameterInspector {
public object BeforeCall(string operationName, object[] inputs) {
int x = (int)inputs[0];
int y = (int)inputs[1];
if (x < 0 || y < 0)
throw new FaultException("參數不能為負數");
return null; // correlationState
}
public void AfterCall(string operationName, object[] outputs, object returnValue, object correlationState) { }
}
public class CalculatorParameterValidation : Attribute, IOperationBehavior {
public void ApplyClientBehavior(OperationDescription od, ClientOperation co) {
co.ParameterInspectors.Add(new CalculatorParameterInspector());
}
public void ApplyDispatchBehavior(OperationDescription od, DispatchOperation dop) {
dop.ParameterInspectors.Add(new CalculatorParameterInspector());
}
// AddBindingParameters, Validate 留空
}
public class CalculatorParameterValidation : Attribute, IParameterInspector, IOperationBehavior {
// IParameterInspector 實現...
// IOperationBehavior 實現中直接 Add(this) 而非 new Inspector()
}
public class PrintMessageInspectorBehavior : IDispatchMessageInspector, IEndpointBehavior {
// IDispatchMessageInspector 實現略...
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime) {
clientRuntime.MessageInspectors.Add(this);
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) {
endpointDispatcher.DispatchRuntime.MessageInspectors.Add(this);
}
}
public void ApplyDispatchBehavior(ServiceDescription sd, ServiceHostBase shb) {
foreach (ChannelDispatcher cd in shb.ChannelDispatchers) {
foreach (EndpointDispatcher ed in cd.Endpoints) {
ed.DispatchRuntime.MessageInspectors.Add(this);
}
}
}
public class MyBehaviorExtensionElement : BehaviorExtensionElement {
public override Type BehaviorType => typeof(MyServiceBehavior);
protected override object CreateBehavior() => new MyServiceBehavior();
// 自定義屬性
[ConfigurationProperty("providerName", IsRequired = true)]
public string ProviderName {
get => (string)this["providerName"];
set => this["providerName"] = value;
}
}
<system.serviceModel>
<extensions>
<behaviorExtensions>
<add name="myBehavior"
type="MyNamespace.MyBehaviorExtensionElement, MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</behaviorExtensions>
</extensions>
<behaviors>
<serviceBehaviors>
<behavior>
<myBehavior providerName="MyProvider" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
避坑指南: type 屬性必須包含完整類型名、組件名、版本、文化、公鑰 token,**每個逗號後必須有一空格**,否則反射載入失敗。
通過 IOperationBehavior.ApplyDispatchBehavior 設定 DispatchOperation.Invoker:
public class MyOperationInvokerBehavior : Attribute, IOperationBehavior {
public void ApplyDispatchBehavior(OperationDescription od, DispatchOperation dop) {
dop.Invoker = new MyOperationInvoker(dop.Invoker); // 裝飾模式包裝原調用器
}
}
FaultException,避免通道錯誤導致連線中斷。掌握行為擴展,即掌握了 WCF 管線的「神經中樞」,能優雅實現日誌、驗證、效能監控、安全審計等橫切關注點。