技术开发 频道

聚焦WCF行为的扩展

   特别注意的是<extensions>下的 type值,必须是类型的full name。第一个逗点前的内容为完整的类型名(包括命名空间),第二部分为完整的命名空间。Version,Culture以及 PublicKeyToken也是缺一不可的。每个逗点后必须保留一个空格,否则无法正确添加扩展行为的配置。这与反射有关,但太容易让人忽略这一小细节。希望微软能在后来的版本中修订这个瑕疵。

   3、在行为扩展的适当方法中,需要添加参数检查、消息检查或操作调用程序的扩展。这之间存在一定的对应关系。对于参数检查,我们需要在IOperationBehavior接口类型中的ApplyClientBehavior()以及ApplyDispatchBehavior()中添加。例如对于之前的CalculatorParameterInspector,我们可以定义一个类CalculatorParameterValidation:

public class CalculatorParameterValidation:Attribute, IOperationBehavior
{
        
#region IOperationBehavior Members
        
public void AddBindingParameters(OperationDescription operationDescription,
            BindingParameterCollection bindingParameters)
        {
        }

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

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

        
public void Validate(OperationDescription operationDescription)
        {
        }
        
#endregion
}

  如果检查器与扩展行为在职责上没有分离的必要,一个更好的方法是定义一个类同时实现IParameterInspector和IOperationBehavior接口,例如:

public class CalculatorParameterValidation:Attribute, IParameterInspector, IOperationBehavior
{
        
#region IParameterInspector Members
        
public void BeforeCall(string operationName, object[] inputs)
        {
            
int x = inputs[0] as int;
            
int y = inputs[1] as int;
            
if (x <0 || y < 0)
            {
              
throw new FaultException("The number can not be less than zero.");
            }
            
return null;
        }
        
public void AfterCall(string operationName, object[] outputs, object returnValue, object correlationState)
        {
            
//empty;
        }
        
#endregion

        
#region IOperationBehavior Members
        
public void AddBindingParameters(OperationDescription operationDescription,
            BindingParameterCollection bindingParameters)
        {
        }

        
public void ApplyClientBehavior(OperationDescription operationDescription,
            ClientOperation clientOperation)
        {
            CalculatorParameterInspector inspector
= new CalculatorParameterInspector();
            clientOperation.ParameterInspectors.Add(thisinspector);
        }

        
public void ApplyDispatchBehavior(OperationDescription operationDescription,
            DispatchOperation dispatchOperation)
        {
            CalculatorParameterInspector inspector
= new CalculatorParameterInspector();
            dispatchOperation.ParameterInspectors.Add(thisinspector);
        }

        
public void Validate(OperationDescription operationDescription)
        {
        }
        
#endregion
}

  操作调用程序虽然通过IOperationBehavior进行关联,但确是通过DispatchOperation的Invoker属性。假定我们已经定义了一个实现IOperationInvoker的类MyOperationInvoker,则关联的方法为:

public class MyOperationInvokerBehavior : 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 MyOperationInvoker(dispatchOperation.Invoker);
        }
        
public void Validate(OperationDescription operationDescription)
        {
        }
        
#endregion
    }
0
相关文章