using System; using System.ServiceModel; //using Curtain.WCF.Contract; namespace Curtain.WCF.Proxy { /// /// WCF服务代理基类 /// public abstract class WCFProxy : IDisposable//, IWCFProxy where TChannel : class//, IWCFContract { #region 常量 #endregion #region 成员变量 /// /// 终结点的配置名称 /// private string _endpointName = null; private string _serviceName = null; /// /// WCF通道工厂 /// private ChannelFactory _channelFactory = null; /// /// WCF代理配置 /// private WCFProxySetting _setting = null; /// /// WCF代理配置版本 /// private int _settingVersion = 0; #endregion #region 构造 /// /// WCF服务代理基类 /// /// /// /// protected WCFProxy(string endpointName, string settingName, string serviceName) { if (string.IsNullOrWhiteSpace(endpointName)) { throw new ArgumentNullException("endpointName"); } this._endpointName = endpointName; this._serviceName = serviceName; this._setting = WCFProxySetting.CreateSetting(settingName); } /// /// WCF服务代理基类 /// /// /// protected WCFProxy(string endpointName, WCFProxySetting setting, string serviceName) { if (string.IsNullOrWhiteSpace(endpointName)) { throw new ArgumentNullException("endpointName"); } this._endpointName = endpointName; this._serviceName = serviceName; this._setting = (setting == null ? WCFProxySetting.DefaultSetting : setting); } #endregion #region 属性 public string EndpointName { get { return this._endpointName; } } public string ServiceName { get { return this._serviceName; } } /// /// WCF代理配置 /// public WCFProxySetting ProxySetting { get { return this._setting; } } /// /// 信道工厂 /// public ChannelFactory ChannelFactory { get { return this._channelFactory; } } #endregion #region 公有方法 /// /// 执行 /// /// /// 超时(分钟) public virtual void Invoke(Action serviceInvocation, double timeout = 0) { TChannel channel = null;//default(TChannel); IContextChannel contextChannel = null; string methodName = serviceInvocation.Method.ToString(); try { if (this._setting.Type == 1) { channel = this.GetServerInstance(); } else { this.OpenChannelFactory(); channel = this._channelFactory.CreateChannel(); contextChannel = channel as IContextChannel; if (contextChannel != null) { if (timeout > WCFProxySetting.OPERATION_TIMEOUT_MAX) { timeout = WCFProxySetting.OPERATION_TIMEOUT_MAX; } if (timeout > 0) { contextChannel.OperationTimeout = TimeSpan.FromMinutes(timeout); } } } serviceInvocation(channel); this.InvokeDone(methodName, null, true); } catch (Exception ex) { Exception newEx = this.InvokeException(methodName, ex); if (newEx == null) { return; } throw newEx; } finally { if (contextChannel != null) { try { contextChannel.Close(); } catch { contextChannel.Abort(); } } } } /// /// 执行 /// /// /// /// 超时(分钟) /// public virtual TResult Invoke(Func serviceInvocation, double timeout = 0) { TChannel channel = null;// default(TChannel); IContextChannel contextChannel = null; string methodName = serviceInvocation.Method.ToString(); try { //if (this._setting.Type == 1) //{ // channel = this.GetServerInstance(); //} ////else //if(channel == null) { this.OpenChannelFactory(); channel = this._channelFactory.CreateChannel(); contextChannel = channel as IContextChannel; if (contextChannel != null) { if (timeout > WCFProxySetting.OPERATION_TIMEOUT_MAX) { timeout = WCFProxySetting.OPERATION_TIMEOUT_MAX; } if (timeout > 0) { contextChannel.OperationTimeout = TimeSpan.FromMinutes(timeout); } } } TResult result = serviceInvocation(channel); result = this.InvokeDone(methodName, result); return result; } catch (Exception ex) { Exception newEx = this.InvokeException(methodName, ex); if (newEx == null) { return default(TResult); } throw newEx; } finally { if (contextChannel != null) { try { contextChannel.Close(); } catch { contextChannel.Abort(); } } } } /// /// 关闭通道工厂 /// public void CloseChannelFactory() { try { this._channelFactory.Close(); } catch { this._channelFactory.Abort(); } finally { this._channelFactory = null; } } /// /// 释放分配的资源 /// public void Dispose() { this._setting = null; this.CloseChannelFactory(); } #endregion #region 保护方法 protected virtual TChannel GetServerInstance() { //throw new NotImplementedException(); return null; } /// /// 异常处理 /// 1.写日志 /// 2.客户端连接异常处理 /// 3.服务端异常处理 /// /// /// /// /// 抛出未处理异常 protected virtual Exception InvokeException(string methodName, Exception ex) { return ex; } /// /// 请求被处理后 /// 1.如果服务端异常已处理,写日志,提示消息等处理。 /// /// protected virtual TResult InvokeDone(string methodName, TResult result, bool isOneWay = false) { return result; } #endregion #region 私有方法 /// /// 打开通道工厂 /// protected void OpenChannelFactory() { lock (this) { if (this._channelFactory != null && this._settingVersion != this._setting.Version) { this.CloseChannelFactory(); } if (this._channelFactory == null) { this._settingVersion = this._setting.Version; EndpointAddress remoteAddress = new EndpointAddress(this._setting.GetEndpointAddress(this._serviceName)); this._channelFactory = new ChannelFactory(this._endpointName, remoteAddress); this._channelFactory.Open(); } } } #endregion } }