在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. TortoiseSVN历史版本安装及svn服务器搭建

    一.TortoiseSVN安装 1.TortoiseSVN下载 网址如下:https://tortoisesvn.net/downloads.html   进入客户端下载页面,根据你的电脑选择是64位 ...

  2. CSS之纯CSS画的基本图形(矩形、圆形、三角形、多边形、爱心、八卦等)

    图形包括基本的矩形.圆形.椭圆.三角形.多边形,也包括稍微复杂一点的爱心.钻石.阴阳八卦等.当然有一些需要用到CSS3的属性,所以在你打开这篇文章的时候,我希望你用的是firefox或者chrome, ...

  3. 算法笔记_014:合并排序(Java)

    1 问题描述 给定一组数据,使用合并排序得到这组数据的非降序排列. 2 解决方案 2.1 合并排序原理简介 引用自百度百科: 合并排序是建立在归并操作上的一种有效的排序算法.该算法是采用分治法(Div ...

  4. InnoDB的约束机制

    数据完整性 关系型数据库系统和文件系统的一个不同点是,关系数据库本身能保证存储数据的完整性,不需要应用程序的控制,而文件系统一般需要在程序端进行控制.几乎所有的关系型数据库都提供了约束(constra ...

  5. 试制品 (nyoj 542)

    模拟 a 反应物集合 ; b 生成物集合; c 存在的化合物或单质集合; ans 新生成化合物集合 1.如果反应无均在已生成的化合物集合中,则完成反应,将合成物加入c集合 2.对每个方程式的反应物进行 ...

  6. [kuangbin带你飞]专题六 最小生成树 POJ 2421 Constructing Roads

    给一个n个点的完全图 再给你m条道路已经修好 问你还需要修多长的路才能让所有村子互通 将给的m个点的路重新加权值为零的边到边集里 然后求最小生成树 #include<cstdio> #in ...

  7. 免备案速度快最新优惠码,vps评测digitalocean对比vultr和linode

    在无数海外vps服务器供应商中,vultr价格便宜,有日本机房不限购,对中国大陆速度友好:linode是经典款,服务器最稳定,内存翻倍,起步就是2GB,性价比高:digitalocean服务器创建速度 ...

  8. Canvas裁剪和Region、RegionIterator

    主要是看这边文章学习:http://blog.csdn.net/lonelyroamer/article/details/8349601 Region.op参数 DIFFERENCE(0), //最终 ...

  9. spring-事务实现原理

    spring事务的实现原理:aop. aop的两种实现方式: 1.动态代理: 事务方法与调用方法不能在同一个类中,否则事务不生效.解决方案,自己注入自己(实质注入的是代理类). 实现方式:jdk动态代 ...

  10. Python学习笔记——基础篇【第六周】——Subprocess模块

    执行系统命令 可以执行shell命令的相关模块和函数有: os.system os.spawn* os.popen*          --废弃 popen2.*           --废弃 com ...