WCF读取配置动态生成客户端对象
2012-03-15 11:42
435 查看
写一个类,用于动态生成WCFClient对象,无须每个WCF服务生成一个对应的配置,
public class WcfServiceFactory { /// <summary> /// </summary> /// <typeparam name="T"></typeparam> /// <param name="action"></param> /// <param name="host">(127.0.0.1)</param> /// <param name="port">1-65535</param> public static void Execute<T>(string host = null, short port = 0,params Action<T>[] action) where T : class,IDisposable, ICommunicationObject, new() { Execute("COMM",host,port,action); } /// <summary> /// </summary> /// <typeparam name="T"></typeparam> /// <param name="bindingName">设置中Binding的名子.</param> /// <param name="action">The action.</param> /// <param name="host">(127.0.0.1)</param> /// <param name="port">1-65535</param> /// <remarks></remarks> public static void Execute<T>(string bindingName,string host = null, short port = 0,params Action<T>[] action) where T : class,IDisposable, ICommunicationObject, new() { Execute(null, bindingName,host,port, action); } /// <summary> /// 执行WCF /// </summary> /// <typeparam name="T">服务Client类型</typeparam> /// <param name="strServiceUrl">服务URL(如果为空,则从web.Config中读取名子为COMM的URL)</param> /// <param name="bindingName">设置中Binding的名子</param> /// <param name="host">(127.0.0.1)</param> /// <param name="port">1-65535</param> /// <param name="exception">寻常</param> /// <param name="action">要执行服务的方法列表</param> /// <remarks></remarks> public static void Execute<T>(string strServiceUrl, string bindingName, string host = null, short port = 0, Action<Exception> exception = null, params Action<T>[] action) where T : IDisposable, ICommunicationObject, new() { using (var t = GetInstance<T>(strServiceUrl,host,port, bindingName)) { action.ToList().ForEach(f => { if (exception != null) { try { f(t); } catch(Exception e) { exception(e); } } else { f(t); } }); } } /// <summary> /// 执行WCF,并返回值 /// </summary> /// <typeparam name="TClient">服务Client类型</typeparam> /// <typeparam name="TResult">返回值</typeparam> /// <param name="strServiceUrl">服务URL(如果为空,则从web.Config中读取名子为COMM的URL)</param> /// <param name="bindingName">设置中Binding的名子</param> /// <param name="host">(127.0.0.1)</param> /// <param name="port">1-65535</param> /// <param name="exception">寻常</param> /// <param name="action">要执行服务的方法列表</param> /// <returns></returns> public static TResult ExecuteReturn<TClient, TResult>(string strServiceUrl, string bindingName, string host = null, short port = 0, Action<Exception> exception = null, params Func<TClient, TResult>[] action) where TClient : IDisposable, ICommunicationObject, new() { TResult re = default(TResult); using (var t = GetInstance<TClient>(strServiceUrl, host, port, bindingName)) { action.ToList().ForEach(f => { if (exception != null) { try { re = f(t); } catch (Exception e) { exception(e); } } else { re = f(t); } }); } return re; } /// <summary> /// 执行WCF /// </summary> /// <typeparam name="T">服务Client类型</typeparam> /// <param name="strServiceUrl">服务URL(如果为空,则从web.Config中读取名子为COMM的URL)</param> /// <param name="bindingName">设置中Binding的名子</param> /// <param name="host">(127.0.0.1)</param> /// <param name="port">1-65535</param> /// <param name="action">要执行服务的方法列表</param> /// <remarks></remarks> public static void Execute<T>(string strServiceUrl, string bindingName, string host = null, short port = 0, params Action<T>[] action) where T : IDisposable, ICommunicationObject, new() { Execute(null, bindingName, host, port,null, action); } public static T GetInstance<T>(string strServiceUrl) where T : IDisposable, ICommunicationObject, new() { return GetInstance<T>(strServiceUrl,null); } /// <summary> /// 返回设置中名子为bindingName的Uri /// </summary> /// <param name="bindingName"></param> /// <returns></returns> public static Uri GetEndpointAddress(string bindingName) { var client = WCFConfigHelper.GetChannelEndpointElement(bindingName,false); if(client!=null) { return client.Address; } return null; } /// <summary> /// 创建一个WCF服务实例 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="strServiceUrl">WCF Service Url</param> /// <param name="host">(127.0.0.1)</param> /// <param name="port">1-65535</param> /// <param name="bindingName">设置中Binding的名子</param> /// <returns>WCF服务实例</returns> /// <remarks></remarks> public static T GetInstance<T>(string strServiceUrl = null,string host = null,short port = 0,string bindingName = "COMM") where T : IDisposable, ICommunicationObject, new() { T _instance = default(T); string serviceUri = strServiceUrl; object[] paras = new object[2]; BasicHttpBinding binding = new BasicHttpBinding(BasicHttpSecurityMode.None); //返回设置 var bindConfig = WCFConfigHelper.GetBasicHttpBindingElement(bindingName, true); bindConfig.ApplyConfiguration(binding);//应用设置 EndpointAddress address; if (serviceUri == null)//从设置中返回URL { var client = WCFConfigHelper.GetChannelEndpointElement(bindingName, true); var endpoint = client.Address; string url = string.Format(endpoint.ToString(), GetServerName<T>()); Uri temp = new Uri(url); Uri newUri = temp; if (host != null)//如果输入参数中有HOST,则替换源设置中的HOST及端口 { if (port == 0) port = 80; newUri = new Uri(string.Format("http://{0}:{1}{2}", host, port, temp.PathAndQuery)); } //WCF访问地址 address = new EndpointAddress(newUri); } else { address = new EndpointAddress(strServiceUrl); } //WCF设置及WCF地址 paras[0] = binding; paras[1] = address; ConstructorInfo constructor; try { Type[] types = new Type[2]; types[0] = typeof(Binding); types[1] = typeof(EndpointAddress); constructor = typeof(T).GetConstructor(types);//声明调用哪个构造 } catch (Exception) { return _instance; } if (constructor != null) _instance = (T)constructor.Invoke(paras);//调用构造生成WCF访问类 return _instance; } /// <summary> /// 根据CLIENT返回接口类型名子, /// </summary> /// <typeparam name="T"></typeparam> /// <returns></returns> private static string GetServerName<T>() { Type t = typeof (T); var interFace = t.GetInterfaces().FirstOrDefault(w => w.IsDefined(typeof (ServiceContractAttribute), false)); if (interFace != null) { return interFace.Name; } return ""; } }
读取设置类
/// <summary>/// 读取WCF设置/// </summary>public static class WCFConfigHelper{#region Section/// <summary>/// 返回Bindings设置/// </summary>/// <returns></returns>public static BindingsSection GetBindingsSection(){return ConfigurationManager.GetSection("system.serviceModel/bindings") as BindingsSection;}/// <summary>/// 返回ServicesSection设置/// </summary>/// <returns></returns>public static ServicesSection GetServicesSection(){return ConfigurationManager.GetSection("system.serviceModel/services") as ServicesSection;}/// <summary>/// 返回BehaviorsSection设置/// </summary>/// <returns></returns>public static BehaviorsSection GetBehaviorsSection(){return ConfigurationManager.GetSection("system.serviceModel/behaviors") as BehaviorsSection;}/// <summary>/// 返回ClientSection设置/// </summary>/// <returns></returns>public static ClientSection GetClientSection(){return ConfigurationManager.GetSection("system.serviceModel/client") as ClientSection;}#endregion#region Binding/// <summary>/// 返回BasicHttpBinding设置/// </summary>/// <returns></returns>public static BasicHttpBindingElement GetBasicHttpBindingElement(string name,bool returnDefault){var list = GetBindingsSection().BasicHttpBinding.Bindings.Cast<BasicHttpBindingElement>();var re = list.FirstOrDefault(w => w.Name == name);if (re == null && returnDefault) re = list.FirstOrDefault();return re;}/// <summary>/// 返回NetTcpBindingElement设置/// </summary>/// <returns></returns>public static NetTcpBindingElement GetNetTcpBindingElement(string name,bool returnDefault){var list = GetBindingsSection().NetTcpBinding.Bindings.Cast<NetTcpBindingElement>();var re = list.FirstOrDefault(w => w.Name == name);if (re == null && returnDefault) re = list.FirstOrDefault();return re;}/// <summary>/// 返回WSHttpBindingElement设置/// </summary>/// <returns></returns>public static WSHttpBindingElement GetWSHttpBindingElement(string name, bool returnDefault){var list = GetBindingsSection().WSHttpBinding.Bindings.Cast<WSHttpBindingElement>();var re = list.FirstOrDefault(w => w.Name == name);if (re == null && returnDefault) re = list.FirstOrDefault();return re;}#endregion#region Behaviors/// <summary>/// 返回ServiceBehaviorElement设置/// </summary>/// <returns></returns>public static ServiceBehaviorElement GetServiceBehaviorElement(string name, bool returnDefault){var list = GetBehaviorsSection().ServiceBehaviors.Cast<ServiceBehaviorElement>();var re = list.FirstOrDefault(w => w.Name == name);if (re == null && returnDefault) re = list.FirstOrDefault();return re;}#endregion/// <summary>/// 返回设置是的ChannelEndpointElement/// </summary>/// <param name="name"></param>/// <param name="returnDefault"></param>/// <returns></returns>public static ChannelEndpointElement GetChannelEndpointElement(string name, bool returnDefault){var list = GetClientSection().Endpoints.Cast<ChannelEndpointElement>();var re = list.FirstOrDefault(w => w.Name == name);if (re == null && returnDefault) re = list.FirstOrDefault();return re;}}使用方法
#region 通用Execute/// <summary>/// 使用设置接口设置执行WCF(默认接口设置为COMM)/// </summary>/// <typeparam name="TClient">WCF客户端代理</typeparam>/// <param name="port">设置WCF服务的端口号</param>/// <param name="action">要执行WCF的方法</param>/// <param name="host">设置WCF服务的服务器名称或IP</param>public static void Execute<TClient>(string host = null, short port = 0, Action<TClient> action = null)where TClient : class, IDisposable, ICommunicationObject, new(){Execute(null, "COMM", host, port, action);}/// <summary>/// 执行WCF/// </summary>/// <typeparam name="TClient">服务Client类型</typeparam>/// <param name="strServiceUrl">服务URL(如果为空,则从web.Config中读取名子为COMM的URL)</param>/// <param name="binding">设置中Binding的名子.</param>/// <param name="port">设置WCF服务的端口号</param>/// <param name="exceptionAction">调用WCF错误时执行的方法</param>/// <param name="action">要执行服务的方法列表</param>/// <param name="host">设置WCF服务的服务器名称或IP</param>/// <remarks></remarks>public static void Execute<TClient>(string strServiceUrl = null, string binding = null, string host = null,short port = 0, Action<Exception> exceptionAction = null, Action<TClient> action = null)where TClient : IDisposable, ICommunicationObject, new(){WcfServiceFactory.Execute(strServiceUrl, binding, host, port, exceptionAction, action);}/// <summary>////// </summary>/// <param name="strServiceUrl"></param>/// <param name="binding"></param>/// <param name="host"></param>/// <param name="port"></param>/// <param name="action"></param>/// <typeparam name="TClient"></typeparam>public static void Execute<TClient>(string strServiceUrl = null, string binding = null, string host = null,short port = 0, Action<TClient> action = null)where TClient : IDisposable, ICommunicationObject, new(){Execute(strServiceUrl, binding, host, port, null, action);}#endregion#region 通用ExecuteReturn/// <summary>////// </summary>/// <typeparam name="TClient">服务Client类型</typeparam>/// <typeparam name="TResult">执行WCF服务的返回数据类型</typeparam>/// <param name="strServiceUrl">设置WCF服务的地完整地址</param>/// <param name="binding">设置中Binding的名子.</param>/// <param name="host">设置WCF服务的服务器名称或IP</param>/// <param name="port">设置WCF服务的端口</param>/// <param name="exceptionAction"></param>/// <param name="action">要执行WCF的方法</param>/// <returns></returns>public static TResult ExecuteReturn<TClient, TResult>(string strServiceUrl = null, string binding = null,string host = null, short port = 0,Action<Exception> exceptionAction = null,Func<TClient, TResult> action = null)where TClient : IDisposable, ICommunicationObject, new(){return WcfServiceFactory.ExecuteReturn(strServiceUrl, binding, host, port, exceptionAction, action);}#endregion添加配置,aaa无用,但必须设置,COMM在调用时使用,{0}为服务名,自动匹配
<endpoint address="http://localhost:1234/Services/{0}.svc" binding="basicHttpBinding"contract="aaa" name="COMM" />
<basicHttpBinding><binding name="AAA" closeTimeout="00:01:00" openTimeout="00:01:00"receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false"bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"maxBufferSize="96553600" maxBufferPoolSize="52428800" maxReceivedMessageSize="96553600"messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"useDefaultWebProxy="true"><readerQuotas maxDepth="3200" maxStringContentLength="81920000"maxArrayLength="91638400" maxBytesPerRead="409600" maxNameTableCharCount="91638400" /><security mode="None"><transport clientCredentialType="None" proxyCredentialType="None"realm="" /><message clientCredentialType="UserName" algorithmSuite="Default" /></security></binding></basicHttpBinding>
相关文章推荐
- 读取配置文件动态创建对象[C++]
- C#中通过读取配置文件动态创建泛型对象
- WCF生成客户端代理对象的两种方法的解释
- 使用svcutil工具自动生成wcf调用的客户端代码和配置文件
- WCF生成客户端对象方式解析
- WCF生成客户端对象方式解析
- JavaSE8基础 Properties+反射 读取配置文件,使用无参构造函数生成类的实例对象
- 16. 在工厂方法中读取配置,生成可配置化的对象
- WCF中可以使用SVCUtil.exe生成客户端代理类和配置文件
- 动态修改WCF客户端配置文件终结点的地址的几种方法
- WCF通过SVCUtil.exe生成客户端代理类和配置文件(转)
- WCF中可以使用SVCUtil.exe生成客户端代理类和配置文件
- log4j2 不使用配置文件,动态生成logger对象
- WCF随客户端软件一起发布,客户端自动识别WCF服务地址,不通过配置文件绑定WCF服务,客户端动态获取版本号
- 使用SvcUtil.exe生成客户端代码和配置、WCF Test Client调试WCF
- log4j2 不使用配置文件,动态生成logger对象
- C#中通过读取配置文件动态创建泛型对象
- C#读取Excel数据动态生成对象并进行序列化
- WCF实体对象客户端引用时生成多余参数"××Specified",且值类型数据赋值无法传递值时必须付××Specified=true
- WCF 系列:通过SvcUtil.exe生成客户端代码和配置