真实代理(RealProxy)在WCF中的运用

在WCF中,当我们在调用服务端的方法时,一般有两点需要考虑:1、捕获服务端的异常信息,记录日志;2、及时关闭会话信道,当调用超时或调用失败时及时中断会话信道。我们一般会像下面这样处理(以CalculatorService为例):

using (ChannelFactory<ICalculatorService> channelFactory = new ChannelFactory<ICalculatorService>("CalculatorService"))
            {
                ICalculatorService proxy = channelFactory.CreateChannel();
                var commObj = proxy as ICommunicationObject;
                 try
                     {
                    Console.WriteLine("x + y = {2} when x = {0} and y = {1}", 1, 2, proxy.Add(1, 2));
                    commObj.Close();
                     }
                  catch (CommunicationException)
                    {
                        commObj.Abort();
                    }
                    catch (TimeoutException)
                    {
                        commObj.Abort();
                    }
                    catch (Exception)
                    {
                        //TODO:记录异常到日志
                        commObj.Abort();
                        throw;
                    }
            }

以上这种处理方式完全可以满足我们的需要,但存在一个问题,每次调用服务端的方法时都需要手工加上这些异常捕获代码,如果服务有很多方法时,这样势必会存在大量功能重复的代码,可复用性很差。我们可以借鉴一下AOP的思想,具体来说就是对服务端方法调用进行拦截。对于.Net应用来说,自定义RealProxy是实现方法调用拦截最简单的一种方式。下面是一个自定义RealProxy的例子:

public class CalculatorServiceRealProxy : RealProxy
    {
        public CalculatorServiceRealProxy():base(typeof(ICalculatorService)){}
        public override IMessage Invoke(IMessage msg)
        {
            IMethodReturnMessage methodReturn = null;
            IMethodCallMessage methodCall = (IMethodCallMessage)msg;
            var client = new ChannelFactory<ICalculatorService>("CalculatorService");
            var channel = client.CreateChannel();
            try
            {
               object[] copiedArgs = Array.CreateInstance(typeof(object), methodCall.Args.Length) as object[];
                methodCall.Args.CopyTo(copiedArgs, 0);
                object returnValue = methodCall.MethodBase.Invoke(channel, copiedArgs);
                methodReturn = new ReturnMessage(returnValue,
                                                copiedArgs,
                                                copiedArgs.Length,
                                                methodCall.LogicalCallContext,
                                                methodCall);
                //TODO:Write log
            }
            catch (Exception ex)
            {
                var exception = ex;
                if (ex.InnerException != null)
                    exception = ex.InnerException;
                methodReturn = new ReturnMessage(exception, methodCall);
            }
            finally
            {
                var commObj = channel as ICommunicationObject;
                if (commObj != null)
                {
                    try
                    {
                        commObj.Close();
                    }
                    catch (CommunicationException)
                    {
                        commObj.Abort();
                    }
                    catch (TimeoutException)
                    {
                        commObj.Abort();
                    }
                    catch (Exception)
                    {
                        commObj.Abort();
                        //TODO:Logging exception
                        throw;
                    }
                }
            }
            return methodReturn;
        }
    }

方法调用:

static void Main(string[] args)
        {

        ICalculatorService proxy = (ICalculatorService)new CalculatorServiceRealProxy().GetTransparentProxy();

            Console.WriteLine("x + y = {2} when x = {0} and y = {1}", 1, 2, proxy.Add(1, 2));
            Console.WriteLine("x - y = {2} when x = {0} and y = {1}", 1, 2, proxy.Subtract(1, 2));
            Console.WriteLine("x * y = {2} when x = {0} and y = {1}", 1, 2, proxy.Multiply(1, 2));
            Console.WriteLine("x / y = {2} when x = {0} and y = {1}", 1, 2, proxy.Divide(1, 2));

            Console.ReadKey();
        }

通过自定义的RealProxy创建TransparentProxy供客户端代码调用,对于通过TransparentProxy的每一次调用,都会被RealProxy接管,这样我们就可以在RealProxy中加入异常捕获、记录日志等非业务逻辑代码,这些代码在每次调用服务端方法时都会被调用。

源代码下载  (工程ConsoleHosting为服务端,工程Client3为客户端)

时间: 2024-08-02 21:55:19

真实代理(RealProxy)在WCF中的运用的相关文章

.net 真实代理和透明代理的交互

1 1.本地代理调用 2 3 4 using System; 5 using System.Runtime.Remoting ; 6 using System.Runtime.Remoting.Services ; 7 using System.Runtime.Remoting.Activation ; 8 using System.Runtime.Remoting.Proxies ; 9 using System.Runtime.Remoting.Messaging ; 10 11 12 /*

.net 自定义AOP,透明代理与真实代理

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.Remoting.Messaging; using System.Runtime.Remoting.Activation; using System.Runtime.Remoting; using NewAop; using System.Runtime.Remoting.Proxie

SSL/TLS原理详解与WCF中的WS-Security

SSL/TLS作为一种互联网安全加密技术 1. SSL/TLS概览 1.1 整体结构 SSL是一个介于HTTP协议与TCP之间的一个可选层,其位置大致如下: SSL:(Secure Socket Layer,安全套接字层),为Netscape所研发,用以保障在Internet上数据传输之安全,利用数据加密(Encryption)技术,可确保数据在网络上之传输过程中不会被截取.当前版本为3.0.它已被广泛地用于Web浏览器与服务器之间的身份认证和加密数据传输.SSL协议位于TCP/IP协议与各种应

WCF中数据契约之已知类型的几种公开方式

WCF中传输的数据不想传统的面向对象编程,它只传递了一些对象的属性,但是自身并不知道自己属于什么对象,所以,他没有子类和父类的概念,因而也就没有Is-a的关系,所以在WCF中,如果想维持这种继承关系,就需要做一些特殊的处理了. 假设有如下定义, namespace KnownTypeExampleInterface{    [DataContract]    public class Employee    {        [DataMember]        public string N

跟我一起学WCF(12)——WCF中Rest服务入门

一.引言 要将Rest与.NET Framework 3.0配合使用,还需要构建基础架构的一些部件.在.NET Framework 3.5中,WCF在System.ServiceModel.Web组件中新增了编程模型和这些基础架构部件. 新编程模型有两个主要的新属性:WebGetAttribute和WebInvokeAttribute,还有一个URI模板机制,帮助你声明每种方法响应使用的URI和动词..NET Framework还提供了一个新的绑定(WebHttpBinding)和新的行为(We

跟我一起学WCF(11)——WCF中队列服务详解

一.引言 在前面的WCF服务中,它都要求服务与客户端两端都必须启动并且运行,从而实现彼此间的交互.然而,还有相当多的情况希望一个面向服务的应用中拥有离线交互的能力.WCF通过服务队列的方法来支持客户端和服务之间的离线工作,客户端将消息发送到一个队列中,再由服务对它们进行处理.下面让我们具体看看WCF中的队列服务. 二.WCF队列服务的优势 在介绍WCF队列服务之前,首先需要了解微软消息队列(MSMQ).MSMQ是在多个不同应用之间实现相互通信的一种异步传输模式,相互通信的应用可以分布在同一台机器

跟我一起学WCF(10)——WCF中事务处理

一.引言 好久没更新,总感觉自己欠了什么一样的,所以今天迫不及待地来更新了,因为后面还有好几个系列准备些,还有很多东西需要学习总结的.今天就来介绍下WCF对事务的支持. 二.WCF事务详解 2.1 事务概念与属性 首先,大家在学习数据库的时候就已经接触到事务这个概念了.所谓事务,它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单元.例如,银行转账功能,这个功能涉及两个逻辑操作 从一个账户A中扣钱 另一个账户B增加对应的钱. 现实生活中,这两个操作需要要么都执行,要么都不

WCF中配置文件解析

WCF中配置文件解析 2014-06-14 参考 WCF中配置文件解析 返回 在WCF Service Configuration Editor的使用中,我们通过配置工具自动生成了WCF服务端的config文件.现在我们来看下这个配置文件各个标签的意义: 1 <?xml version="1.0" encoding="utf-8" ?> 2 <configuration> 3 <!-- 这个程序集我们在项目中有引用的 --> 4

Entity Framework在WCF中序列化的问题

问题描述 如果你在WCF中用Entity Framework来获取数据并返回实体对象,那么对下面的错误一定不陌生. 接收对 http://localhost:5115/ReService.svc 的 HTTP 响应时发生错误.这可能是由于服务终结点绑定未使用 HTTP 协议造成的. 这还可能是由于服务器中止了 HTTP 请求上下文(可能由于服务关闭)所致.有关详细信息,请参见服务器日志. 这就是因为在返回数据的时候,序列化失败,导致WCF服务自动停止了. 为什么会序列化失败 为了方便说明,我们先