转载自CSDN的ALLsharps 原始链接:http://blog.csdn.net/allsharps/article/details/7356301
写一个类,用于动态生成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>