在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为客户端)

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

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

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.R ...

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

    .本地代理调用 using System; using System.Runtime.Remoting ; using System.Runtime.Remoting.Services ; using ...

  3. [No0000126]SSL/TLS原理详解与WCF中的WS-Security

    SSL/TLS作为一种互联网安全加密技术 1. SSL/TLS概览 1.1 整体结构 SSL是一个介于HTTP协议与TCP之间的一个可选层,其位置大致如下: SSL:(Secure Socket La ...

  4. 在Wcf中应用ProtoBuf替代默认的序列化器

    Google的ProtoBuf序列化器性能的牛逼已经有目共睹了,可以把它应用到Socket通讯,队列,Wcf中,身为dotnet程序员一边期待着不久后Grpc对dotnet core的支持更期待着Wc ...

  5. WCF初探-28:WCF中的并发

    理解WCF中的并发机制 在对WCF并发机制进行理解时,必须对WCF初探-27:WCF中的实例化进行理解,因为WCF中的并发特点是伴随着服务实例上下文实现的.WCF的实例上下文模型可以通过Instanc ...

  6. WCF初探-27:WCF中的实例化

    理解WCF中的实例化机制 “实例化”是指对用户定义的服务对象以及与其相关的 InstanceContext 对象的生存期的控制.也就是说我们的客户端程序在调用服务端方法时,需要实例化一个服务端代理类对 ...

  7. WCF初探-26:WCF中的会话

    理解WCF中的会话机制 在WCF应用程序中,会话将一组消息相互关联,从而形成对话.会话”是在两个终结点之间发送的所有消息的一种相互关系.当某个服务协定指定它需要会话时,该协定会指定所有调用(即,支持调 ...

  8. WCF初探-25:WCF中使用XmlSerializer类

    前言 在上一篇WCF序列化和反序列化中,文章介绍了WCF序列化和反序列化的机制,虽然WCF针对序列化提供了默认的DataContractSerializer序列化引擎,但是WCF还支持其他的序列化引擎 ...

  9. WCF中常用的binding方式

    WCF中常用的binding方式: BasicHttpBinding: 用于把 WCF 服务当作 ASMX Web 服务.用于兼容旧的Web ASMX 服务.WSHttpBinding: 比 Basi ...

随机推荐

  1. PHP连接MSSQL数据库案例,PHPWAMP多个PHP版本连接SQL Server数据库

    课前小知识普及:MSSQL和SQL Server是同一个软件,叫法不同而已,MSSQL全称是Microsoft SQL Server,MSSQL是简写,有些人则喜欢直接叫SQL Server,我就比较 ...

  2. CentOS 7下安装X Window

    1.网上其他人都这么说: yum check-update yum groupinstall "X Window System" ... 但是运行yum groupinstall  ...

  3. >> 计算机的数据表示

    1. 采用二进制 2. 负数采用补码表示 3. 乘法处理 4. 浮点数

  4. nyoj 592 spiral grid(广搜)

    题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=592 解决以下问题后就方便用广搜解: 1.将数字坐标化,10000坐标为(0,0),这样就 ...

  5. sparksql中行转列

    进入sparksql beeline -u "jdbc:hive2://172.16.12.46:10015" -n spark -p spark -d org.apache.hi ...

  6. yarn的调度器

    三种调度器 1.FIFO Scheduler 把应用按提交的顺序排成一个队列,这是一个先进先出队列,在进行资源分配的时候,先给队列中最头上的应用进行分配资源,等最前面的应用需求满足后再给下一个分配,以 ...

  7. python 基础篇第一篇

    本节内容 1.python介绍 2.发展史 3.python2和python3 4.安装 5.简单程序,hello world程序 6.变量 7.用户输入 8.模块初识 9..pyc是什么? 10.数 ...

  8. 中文版的jqGrid实例大全

    中文版的jqGrid实例大全 http://blog.mn886.net/jqGrid/

  9. Tomcat 6 跨域的支持

    1.添加2个jar包 这个我是自己保存在云端的 cors-filter-1.7.jar java-property-utils-1.9.jar tomcat7以后自动支持 2.tomcat 下面的we ...

  10. php stdClass类的用法

    stdClass是PHP的一个基类,所有的类几乎都继承这个类,所以任何时候任何地方都可以被new,可以让这个变量成为一个object.同时,这个基类又有一个特殊的地方,就是没有方法.凡时用new st ...