擴充套件WCF自定義行為(二)

iDotNetSpace發表於2009-07-24

上一篇文章中介紹了WCF執行時體系結構及客戶、伺服器端的擴充套件點。下面以一個簡單的Demo來演示擴充套件WCF的執行時行為。原始碼下載

假設有一個WCF服務介面,提供以使用者名稱進行使用者身份編號的查詢。


[ServiceContract] 
    
public interface IIdentityService
    {
        [IdentityValidate]
        [IdentityCache] 
        [OperationContract]
        
int GetIDByName(string name);
}

一,自定義引數檢查器

假設業務規則要求IIdentityService服務介面的使用者名稱引數不能為空,且必須不少於3個字元。在這種情況下,我們需要在伺服器端進行引數檢查,此檢查在服務介面操作(GetIDByName)呼叫前執行,如果引數檢查不通過,丟擲異常,終止執行後續的操作呼叫。自定義引數檢查器都實現IParameterInspector介面。該介面定義兩個方法:AfterCallBeforeCall,分別是在服務介面操作呼叫前和呼叫後進行引數檢查。


public class NameInspector : IParameterInspector
    {
        
int identityParamIndex;

        
public NameInspector() : this(0) { }

        
public NameInspector(int ParamIndex)
        {
            
this.identityParamIndex = ParamIndex;
        }

        
#region IParameterInspector Members

        
public void AfterCall(string operationName, object[] outputs, object returnValue, object correlationState)
        {
        }

        
public object BeforeCall(string operationName, object[] inputs)
        {
            
string Param = inputs[this.identityParamIndex] as string;
            
if (Param==null||Param .Length <3)
                
throw new FaultException("Invalid name. ");
            
return null;
        }

        
#endregion
}

同時,可以定義一個申明標籤來新增這個自定義引數檢查器到WCF的執行時行為中。該標籤實現IOperationBehavior介面。


public class IdentityValidateAttribute : Attribute, IOperationBehavior
    {
        
#region IOperationBehavior Members

        
public void AddBindingParameters(OperationDescription operationDescription,
            BindingParameterCollection bindingParameters)
        {
        }

        
public void ApplyClientBehavior(OperationDescription operationDescription,
            ClientOperation clientOperation)
        {
            NameInspector nameInspector 
= new NameInspector();
            clientOperation.ParameterInspectors.Add(nameInspector);
        }

        
public void ApplyDispatchBehavior(OperationDescription operationDescription,
            DispatchOperation dispatchOperation)
        {
            NameInspector nameInspector 
= new NameInspector();
            dispatchOperation.ParameterInspectors.Add(nameInspector);
        }

        
public void Validate(OperationDescription operationDescription)
        {
        }

        
#endregion
    }

 

二,  自定操作呼叫器

假設IIdentityService服務介面需要頻繁地被呼叫、而且每次呼叫的服務端資源開銷比較大。在這種情況下我們希望在服務端操作呼叫中快取服務呼叫的結果。自定義一個服務端操作呼叫器,該操作呼叫器實現IOperationInvoker介面,並在Invoke方法中使用了呼叫結果快取功能。Invoke方法首先嚐試在其快取中查詢引數對應的結果,如果找到則直接返回該結果,如果找不到快取結果則呼叫預設的操作呼叫器獲取結果並快取該結果。


public class IdentityCaching : IOperationInvoker
    {
          IOperationInvoker innerOperationInvoker;
        Dictionary
<stringint> identityCache = new Dictionary<stringint>();

        
public IdentityCaching(IOperationInvoker innerOperationInvoker)
        {
            
this.innerOperationInvoker = innerOperationInvoker;
        }

        
#region IOperationInvoker Members

        
public object[] AllocateInputs()
        {
            
return this.innerOperationInvoker.AllocateInputs();
        }

        
public object Invoke(object instance, object[] inputs, out object[] outputs)
        {
            
string name = inputs[0as string;
            
int value;

            
if (this.identityCache.TryGetValue(name, out value))
            {
                outputs 
= new object[0];
                
return value;
            }
            
else
            {
                value 
= (int)this.innerOperationInvoker.Invoke(
                    instance, inputs, 
out outputs);
                identityCache[name] 
= value;
                
return value;
            }
        }

        
public IAsyncResult InvokeBegin(object instance, object[] inputs, 
            AsyncCallback callback, 
object state)
        {
            
return this.innerOperationInvoker.InvokeBegin(
                instance, inputs, callback, state);
        }

        
public object InvokeEnd(object instance, out object[] outputs, IAsyncResult result)
        {
            
return this.innerOperationInvoker.InvokeEnd(
                instance, 
out outputs, result);
        }

        
public bool IsSynchronous
        {
            
get { return innerOperationInvoker.IsSynchronous;  }
        }

        
#endregion
}

同時,可以定義一個申明標籤來新增這個自定操作呼叫器到WCF的執行時行為中。該標籤實現IOperationBehavior介面。


public class IdentityCacheAttribute: Attribute, IOperationBehavior
    {
        
#region IOperationBehavior Members

        
public void AddBindingParameters(OperationDescription operationDescription,
            BindingParameterCollection bindingParameters)
        {
        }

        
public void ApplyClientBehavior(OperationDescription operationDescription,
            ClientOperation clientOperation)
        {
        }

        
public void ApplyDispatchBehavior(OperationDescription operationDescription,
            DispatchOperation dispatchOperation)
        {
            dispatchOperation.Invoker 
= new IdentityCaching(dispatchOperation.Invoker);
        }

        
public void Validate(OperationDescription operationDescription)
        {
        }

        
#endregion
    }

 

 

總結

WCF的體系結構執行進行大量的執行時自定義,其分佈在排程、代理相互動的整個生命週期。除了執行引數檢查、訊息檢查、訊息格式化、操作選擇、操作呼叫等自定義擴充套件外,還可以定義更高階的擴充套件來處理例項化、併發、定址和安全等事項。這些更高階的擴充套件將在以後的文章中介紹。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12639172/viewspace-610383/,如需轉載,請註明出處,否則將追究法律責任。

相關文章