zoukankan      html  css  js  c++  java
  • 跟着Artech学习WCF扩展(4) 扩展MessageInspector

    自定义MessageInspector

    在client端和service端都有自己的MessageInspector,client端叫做ClientMessageInspector,实现System.ServiceModel.Dispatcher.IClientMessageInspector interface,而service端叫做 DispatchMessageInspector, 实现了System.ServiceModel.Dispatcher.IDispatchMessageInspector interface。DispatchMessageInspector允许你在request message交付到具体的DispatchOperation付诸执行之前或者reply message返回client之前对incoming message/outgoing message进行检验、修改或者其他一些基于message的操作;

    IDispatchMessageInspector的定义很简单

    public interface IDispatchMessageInspector
    {
        // Methods
        object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext);
        void BeforeSendReply(ref Message reply, object correlationState);
    }

    在实际的项目开发中,MessageInspector使用相当广范,比如:我们可以定义自己的MessageInspector实现Logging功能;或者在Client端通过ClientMessageInspector添加一些与业务无关的context信息,并在service通过DispatchMessageInspector将其取出。在本系列后续的部分我将给你一个application context propagation的具体应用。

    剩下的地方在这里:点我

    代码下载:点我

    Client端对 IClientMessageInspector 进行实现

    在service端对IDispatchMessageInspector进行实现

    但Artech在service端对 ICallContextInitializer进行了实现

    出去学习的目的,拼拼代码 也把IDispatchMessageInspector实现了

    不过不知道对不对 忍者  自己拼代码实在是盲人摸像 搞了一天才弄明白,不对是还没弄明白

    通过细查 发现这个扩展 实在是太有用了外星人

    部分代码如下作为备份

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ServiceModel;
    using System.ServiceModel.Channels;
    
    namespace Artech.ContextPropagation
    {
       public class DispatchMessageInspectorTest:System.ServiceModel.Dispatcher.IDispatchMessageInspector
        {
           public bool IsBidirectional
           { get; set; }
    
           public DispatchMessageInspectorTest()
               : this(false)
           {
    
           }
    
           public DispatchMessageInspectorTest(bool isBidirectional)
           {
               this.IsBidirectional = isBidirectional;
           }
    
    
     
    
    
            //DispatchMessageInspector
            public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
            {
                ApplicationContext context = request.Headers.GetHeader<ApplicationContext>(ApplicationContext.ContextHeaderLocalName, ApplicationContext.ContextHeaderNamespace);
                if (context == null)
                {
                    return null;
                }
    
                ApplicationContext.Current = context;
                return ApplicationContext.Current;
            }
    
            public void BeforeSendReply(ref Message reply, object correlationState)
            {
    
                if (!this.IsBidirectional)
                {
                    return;
                }
    
                ApplicationContext context = correlationState as ApplicationContext;
                if (context == null)
                {
                    return;
                }
                MessageHeader<ApplicationContext> contextHeader = new MessageHeader<ApplicationContext>(context);
                OperationContext.Current.OutgoingMessageHeaders.Add(contextHeader.GetUntypedHeader(ApplicationContext.ContextHeaderLocalName, ApplicationContext.ContextHeaderNamespace));
                ApplicationContext.Current = null;
    
            }
    
    
    
    
        }
    }

    =========

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ServiceModel;
    using System.ServiceModel.Description;
    
    namespace Artech.ContextPropagation
    {
        public class DispatchMessageInspectorTestBehavior : IEndpointBehavior
        {
            public bool IsBidirectional
            { get; set; }
    
    
            public DispatchMessageInspectorTestBehavior()
                : this(false)
            {
    
            }
    
            public DispatchMessageInspectorTestBehavior(bool isBidirectional)
            {
                this.IsBidirectional = isBidirectional;
            }
    
    
            public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
            {
              
            }
    
            public void ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
            {
                clientRuntime.MessageInspectors.Add(new ContextAttachingMessageInspector(this.IsBidirectional));
           
            }
    
            public void ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher)
            {
    
                DispatchMessageInspectorTest inspector = new DispatchMessageInspectorTest(this.IsBidirectional);
                endpointDispatcher.DispatchRuntime.MessageInspectors.Add(inspector);
            }
    
            public void Validate(ServiceEndpoint endpoint)
            {
                
            }
        }
    }

    ==============

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ServiceModel.Configuration;
    using System.Configuration;
    
    namespace Artech.ContextPropagation
    {
       public class DispatchMessageInspectorTestElement:BehaviorExtensionElement
        {
           [ConfigurationProperty("isBidirectional", DefaultValue = false)]
           public bool IsBidirectional
           {
               get
               {
                   return (bool)this["isBidirectional"];
               }
               set
               {
                   this["isBidirectional"] = value;
               }
           }
    
            public override Type BehaviorType
            {
                get { return typeof(DispatchMessageInspectorTestBehavior); }
            }
    
            protected override object CreateBehavior()
            {
                return new DispatchMessageInspectorTestBehavior(IsBidirectional);
            }
        }
    }

     

    test
  • 相关阅读:
    Glusterfs之nfs模块源码分析(下)之NFS协议之RPC的实现和NFS协议内容
    GlusterFS之内存池(mempool)使用实例分析
    Glusterfs之nfs模块源码分析(中)之Glusterfs实现NFS服务器
    Glusterfs之rpc模块源码分析(中)之Glusterfs的rpc模块实现(1)
    Glusterfs之rpc模块源码分析(上)之RPC概述
    Glusterfs之rpc模块源码分析(中)之Glusterfs的rpc模块实现(3)
    Glusterfs之rpc模块源码分析(下)之RDMA over TCP的协议栈工作过程浅析
    Glusterfs之rpc模块源码分析(中)之Glusterfs的rpc模块实现(2)
    Glusterfs之nfs模块源码分析(上)之nfs原理和协议
    恋人咒语
  • 原文地址:https://www.cnblogs.com/qqloving/p/2200822.html
Copyright © 2011-2022 走看看