真實代理(RealProxy)在WCF中的運用

來源:互聯網
上載者:User

在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為用戶端)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.