步骤一:创建ChannalFactory<T>的静态工厂:ChannelFactoryCreator
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Collections; using System.ServiceModel; namespace Artech.ServiceProxyFactory { internal static class ChannelFactoryCreator { private static Hashtable channelFactories = new Hashtable(); public static ChannelFactory<T> Create<T>(string endpointName) { if (string.IsNullOrEmpty(endpointName)) { throw new ArgumentNullException("endpointName"); } ChannelFactory<T> channelFactory = null; if(channelFactories.ContainsKey(endpointName)) { channelFactory = channelFactories[endpointName] as ChannelFactory<T>; } if (channelFactory == null) { channelFactory = new ChannelFactory<T>(endpointName); lock (channelFactories.SyncRoot) { channelFactories[endpointName] = channelFactory; } } return channelFactory; } } }
步骤二:创建自定义RealProxy:ServiceRealProxy<T>
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.Remoting.Messaging; using System.Runtime.Remoting.Proxies; using System.ServiceModel; namespace Artech.ServiceProxyFactory { public class ServiceRealProxy<T>: RealProxy { private string _endpointName; public ServiceRealProxy(string endpointName):base(typeof(T)) { if (string.IsNullOrEmpty(endpointName)) { throw new ArgumentNullException("endpointName"); } this._endpointName = endpointName; } public override IMessage Invoke(IMessage msg) { T channel = ChannelFactoryCreator.Create<T>(this._endpointName).CreateChannel(); IMethodCallMessage methodCall = (IMethodCallMessage)msg; IMethodReturnMessage methodReturn = null; object[] copiedArgs = Array.CreateInstance(typeof(object), methodCall.Args.Length) as object[]; methodCall.Args.CopyTo(copiedArgs, 0); try { object returnValue = methodCall.MethodBase.Invoke(channel, copiedArgs); methodReturn = new ReturnMessage(returnValue, copiedArgs, copiedArgs.Length, methodCall.LogicalCallContext, methodCall); (channel as ICommunicationObject).Close(); } catch (Exception ex) { if (ex.InnerException is CommunicationException || ex.InnerException is TimeoutException) { (channel as ICommunicationObject).Abort(); } if (ex.InnerException != null) { methodReturn = new ReturnMessage(ex.InnerException, methodCall); } else { methodReturn = new ReturnMessage(ex, methodCall); } } return methodReturn; } } }
步骤三:创建自定义服务代理工厂:ServiceProxyFactory
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Artech.ServiceProxyFactory { public static class ServiceProxyFactory { public static T Create<T>(string endpointName) { if (string.IsNullOrEmpty(endpointName)) { throw new ArgumentNullException("endpointName"); } return (T)(new ServiceRealProxy<T>(endpointName).GetTransparentProxy()); } } }
步骤四:通过ServiceProxyFactory创建服务代理进行服务调用
ICalculator calculator = ServiceProxyFactory.Create<ICalculator>("calculatorservice"); for (int i = 1; i < 2000; i++) { Console.WriteLine("{3}: x + y = {2} when x = {0} and y = {1}", 1, 2, calculator.Add(1, 2), i); }