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

作者: 时间: 2014-07-25 分类: 技术文章 | 0条评论 |

您的支持,是我前进的动力

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

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

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}12, proxy.Add(12));
        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}12, proxy.Add(12));
    Console.WriteLine(x – y = {2} when x = {0} and y = {1}12, proxy.Subtract(12));
    Console.WriteLine(x * y = {2} when x = {0} and y = {1}12, proxy.Multiply(12));
    Console.WriteLine(x / y = {2} when x = {0} and y = {1}12, proxy.Divide(12));

    Console.ReadKey();
}

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

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

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

下载方法:打开链接–输入验证码–进入下载列表–普通不限速下载。

下载地址:推荐地址 | 备用地址 | 
搜妹子,搜出妹子做壁纸!

本文采用 CC协议 发布,转载请注明:转载自 吾乐吧软件站

本文链接地址:http://www.wuleba.com/?p=25754

发表评论


微软MSDN资源免费订阅,MSDN 我告诉你