代码改变世界

WCF扩展:行为扩展Behavior Extension<二>

2010-10-27 16:27  Virus-BeautyCode  阅读(3227)  评论(6编辑  收藏  举报

 

1 引言

上回说到自定义扩展的第一步,是需要声明行为的类型。也就是通过实现一个行为接口,实现接口中的方法来声明行为的类型。

2 附件自定义行为到Operaiton或者是Endpoint

实现自定义的行为,第二步就是将自定义的行为类挂(附加)到一个Operation或者是Endpoint上去。

自定义的行为如果是和操作有关,就附加到一个operation上;如果和具体的操作没有关系,就附加到一个endpoint上。

附加到操作需要实现System.ServiceModel.Description.IOperationBehavior接口。如果是附加到endpoint上,需要实现System.ServiceModel.Description.IEndpointBehavior接口。

如果是一个实现System.ServiceModel.Dispatcher.IClientMessageFormatter的对象,功能是序列化传输到服务端的数据。按照定义,这是一个操作相关的功能。(可以参考上一篇的定义WCF扩展:行为扩展Behavior Extension<一>

3 通知WCF有关自定义行为的信息

实现自定义的行为,最后需要做的就是将这个行为通知WCF。让WCF知道这个行为的存在。有两种方法可以实现通知:代码和配置。

4 自定义行为示例

下面让我们来实现一个简单的自定义行为

4.1 声明

我们声明一个客户端的消息检查行为类

public class MyClientMessageInspector:IClientMessageInspector 
    {
        #region IClientMessageInspector Members

        public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply,
 object correlationState)
        {
            
        }

        public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, 
System.ServiceModel.IClientChannel channel)
        {
            return null;
        }

        #endregion
    }

4.2 附加

将自定义的message inspector行为附加到客户端的运行时,附加到客户端运行时client runtime的endpoint层面。

 public class MyClientMessageInspector:IClientMessageInspector,IEndpointBehavior 
    {
        #region IClientMessageInspector Members

        public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply,
 object correlationState)
        {
            
        }

        public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, 
System.ServiceModel.IClientChannel channel)
        {
            return null;
        }

        #endregion

        #region IEndpointBehavior Members

        public void AddBindingParameters(ServiceEndpoint endpoint, 
System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
        {
            
        }

        public void ApplyClientBehavior(ServiceEndpoint endpoint, 
ClientRuntime clientRuntime)
        {
            clientRuntime.MessageInspectors.Add(this);
        }

        public void ApplyDispatchBehavior(ServiceEndpoint endpoint, 
EndpointDispatcher endpointDispatcher)
        {
            
        }

        public void Validate(ServiceEndpoint endpoint)
        {
            
        }

        #endregion
    }

4.3 通知

有两种方式来通知WCF这个自定义行为。

1 代码的方式

因为需要添加到客户端的运行时,所以需要在客户端的代码中添加。

public interface IWcfClient
 {
 }
 public class WcfClient:ClientBase<IWcfClient >,IWcfClient 
{
   public WcfClient(string endpointConfigurationName):base(endpointConfigurationName )
   {
        base.Endpoint.Behaviors.Add(new Insfrastructures.MyClientMessageInspector());
   }
}

就是在构造函数中添加自定义的行为。

2 通过自定义配置节的配置的方式

让我们先定义一个行为扩展配置节的类

public class MyBehaviorExtensionElement:BehaviorExtensionElement 
    {

        public override Type BehaviorType
        {
            get { return typeof(MyClientMessageInspector); }
        }

        protected override object CreateBehavior()
        {
            return new MyClientMessageInspector();
        }
    }

 

然后再客户端的config文件中添加

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.serviceModel>
        <client>
            <endpoint 
				address="http://localhost:8000/SimpleService/Endpoint" 
				behaviorConfiguration="SimpleServiceEndpointBehavior"
				binding="customBinding"
                bindingConfiguration="SimpleServiceBinding" 
				contract="Extensibility.ISimple" 
				name="SimpleService" />
        </client>
		<behaviors>
			<endpointBehaviors>
				<behavior 
					name="SimpleServiceEndpointBehavior">
					<myMessageInspector />
				</behavior>
				
			</endpointBehaviors>
		</behaviors>
		<bindings>
			<customBinding>
				<binding name="SimpleServiceBinding">
					<httpTransport/>
				</binding>
			</customBinding>
		</bindings>
		<extensions>
			<behaviorExtensions>
				<add 
					name="myMessageInspector"
					type="Insfrastructures
.MyBehaviorExtensionElement, Insfrastructures
.Server, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
			</behaviorExtensions>
		</extensions>
    </system.serviceModel>
</configuration>

在<extensions> 配置节添加行为扩展的配置节。然后在endpoint的behavior配置节中指定使用扩展中的行为。

 

5 总结

 

5.1 运行在客户端的扩展

实现IOperationBehavior接口,扩展操作相关的行为。

 

代码
public OrderServiceClient()
        {
            
foreach (System.ServiceModel.Description.OperationDescription  o in base.Endpoint.Contract.Operations)
            {
                o.Behaviors.Add(
new MyClientParameterInspector());
            }
        }

 

在客户端的代码中,在构造函数中,给每个操作添加行为。

 

base.Endpoint.Behaviors.Add(new MyClientMessageInspector());

实现IEndpointBehavior接口,扩展endpoint相关的行为,通过上面的代码添加扩展。将行为添加到endpoint的behaviors属性就可以了。

 

 

 

应用到【endpoint终节点】上的行为,也就是实现IEndpointBehavior的行为,才可以通过配置通知WCF。应用到操作上的行为,也就是实现IOperationBehavior的行为,不可以通过配置来通知WCF,可以通过代码添加的方式通知WCF。

但是要记住,客户端的行为扩展的配置信息是要添加到客户端程序的配置文件中的。

 

5.2 运行在服务端的扩展

 

应用到【endpoint终节点】上的行为,也就是实现IEndpointBehavior的行为,才可以通过配置通知WCF。应用到操作上的行为,也就是实现IOperationBehavior的行为,不可以通过配置来通知WCF,可以通过代码添加的方式通知WCF。

 

 

 

操作相关的行为扩展还可以通过继承Attribute,使得操作行为的扩展可以通过在服务实现方法上添加attribute来通知WCF。

 

 

 

 

代码
 public class MyDispatcherParameterInspector:IParameterInspector
    {
        
#region IParameterInspector Members

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

        
public object BeforeCall(string operationName, object[] inputs)
        {
            
return null;
        }

        
#endregion
    }


 
public class MyDispatcherParameterInspectorBehaviorAttribute:Attribute,IOperationBehavior
    {
       

        
#region IOperationBehavior Members

        
public void AddBindingParameters(OperationDescription operationDescription, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
        {
            
        }

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

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

        
public void Validate(OperationDescription operationDescription)
        {
            
        }

        
#endregion
    }


   [MyDispatcherParameterInspectorBehavior]
        
public Entity.Order GetOrderBySeqNo(string orderSeqNo)
        {
            
return orderbc.GetOrderBySeqNo(orderSeqNo);
        }

 

endpoint相关的扩展好像不能通过attribute的方式通知。

 

 

 

6 相关文章

 

 

http://cgeers.wordpress.com/2008/11/09/wcf-extensibility-parameter-inspectors/

 

Technorati 标签: WCF,EXtension,BEhavior