WCF读取配置动态生成客户端对象

转载自CSDN的ALLsharps 原始链接:http://blog.csdn.net/allsharps/article/details/7356301

 

 

写一个类,用于动态生成WCFClient对象,无须每个WCF服务生成一个对应的配置,

 

  1. public class WcfServiceFactory  
  2.    {  
  3.        /// <summary>  
  4.        /// </summary>  
  5.        /// <typeparam name="T"></typeparam>  
  6.        /// <param name="action"></param>  
  7.        /// <param name="host">(127.0.0.1)</param>  
  8.        /// <param name="port">1-65535</param>  
  9.        public static void Execute<T>(string host = nullshort port = 0,params Action<T>[] action) where T : class,IDisposable, ICommunicationObject, new()  
  10.        {  
  11.            Execute("COMM",host,port,action);  
  12.        }  
  13.        /// <summary>  
  14.        /// </summary>  
  15.        /// <typeparam name="T"></typeparam>  
  16.        /// <param name="bindingName">设置中Binding的名子.</param>  
  17.        /// <param name="action">The action.</param>  
  18.        /// <param name="host">(127.0.0.1)</param>  
  19.        /// <param name="port">1-65535</param>  
  20.        /// <remarks></remarks>  
  21.        public static void Execute<T>(string bindingName,string host = nullshort port = 0,params Action<T>[] action) where T : class,IDisposable, ICommunicationObject, new()  
  22.        {  
  23.            Execute(null, bindingName,host,port, action);  
  24.        }  
  25.   
  26.        /// <summary>  
  27.        /// 执行WCF  
  28.        /// </summary>  
  29.        /// <typeparam name="T">服务Client类型</typeparam>  
  30.        /// <param name="strServiceUrl">服务URL(如果为空,则从web.Config中读取名子为COMM的URL)</param>  
  31.        /// <param name="bindingName">设置中Binding的名子</param>  
  32.        /// <param name="host">(127.0.0.1)</param>  
  33.        /// <param name="port">1-65535</param>  
  34.        /// <param name="exception">寻常</param>  
  35.        /// <param name="action">要执行服务的方法列表</param>  
  36.        /// <remarks></remarks>  
  37.        public static void Execute<T>(string strServiceUrl, string bindingName, string host = nullshort port = 0, Action<Exception> exception = nullparams Action<T>[] action) where T : IDisposable, ICommunicationObject, new()  
  38.        {  
  39.            using (var t = GetInstance<T>(strServiceUrl,host,port, bindingName))  
  40.            {  
  41.                action.ToList().ForEach(f =>  
  42.                                            {  
  43.                                                if (exception != null)  
  44.                                                {  
  45.                                                    try  
  46.                                                    {  
  47.                                                        f(t);  
  48.                                                    }  
  49.                                                    catch(Exception e)  
  50.                                                    {  
  51.                                                        exception(e);  
  52.                                                    }  
  53.                                                }  
  54.                                                else  
  55.                                                {  
  56.                                                    f(t);  
  57.                                                }  
  58.                                            });  
  59.            }  
  60.        }  
  61.   
  62.        /// <summary>  
  63.        /// 执行WCF,并返回值  
  64.        /// </summary>  
  65.        /// <typeparam name="TClient">服务Client类型</typeparam>  
  66.        /// <typeparam name="TResult">返回值</typeparam>  
  67.        /// <param name="strServiceUrl">服务URL(如果为空,则从web.Config中读取名子为COMM的URL)</param>  
  68.        /// <param name="bindingName">设置中Binding的名子</param>  
  69.        /// <param name="host">(127.0.0.1)</param>  
  70.        /// <param name="port">1-65535</param>  
  71.        /// <param name="exception">寻常</param>  
  72.        /// <param name="action">要执行服务的方法列表</param>  
  73.        /// <returns></returns>  
  74.        public static TResult ExecuteReturn<TClient, TResult>(string strServiceUrl, string bindingName, string host = nullshort port = 0, Action<Exception> exception = nullparams Func<TClient, TResult>[] action)  
  75.            where TClient : IDisposable, ICommunicationObject, new()  
  76.        {  
  77.            TResult re = default(TResult);  
  78.            using (var t = GetInstance<TClient>(strServiceUrl, host, port, bindingName))  
  79.            {  
  80.                action.ToList().ForEach(f =>  
  81.                                            {  
  82.                                                if (exception != null)  
  83.                                                {  
  84.                                                    try  
  85.                                                    {  
  86.                                                        re = f(t);  
  87.                                                    }  
  88.                                                    catch (Exception e)  
  89.                                                    {  
  90.                                                        exception(e);  
  91.                                                    }  
  92.                                                }  
  93.                                                else  
  94.                                                {  
  95.                                                    re = f(t);  
  96.                                                }  
  97.                                            });  
  98.            }  
  99.            return re;  
  100.        }  
  101.   
  102.        /// <summary>  
  103.        /// 执行WCF  
  104.        /// </summary>  
  105.        /// <typeparam name="T">服务Client类型</typeparam>  
  106.        /// <param name="strServiceUrl">服务URL(如果为空,则从web.Config中读取名子为COMM的URL)</param>  
  107.        /// <param name="bindingName">设置中Binding的名子</param>  
  108.        /// <param name="host">(127.0.0.1)</param>  
  109.        /// <param name="port">1-65535</param>  
  110.        /// <param name="action">要执行服务的方法列表</param>  
  111.        /// <remarks></remarks>  
  112.        public static void Execute<T>(string strServiceUrl, string bindingName, string host = nullshort port = 0, params Action<T>[] action) where T : IDisposable, ICommunicationObject, new()  
  113.        {  
  114.            Execute(null, bindingName, host, port,null, action);  
  115.        }  
  116.        public static T GetInstance<T>(string strServiceUrl) where T : IDisposable, ICommunicationObject, new()  
  117.        {  
  118.            return GetInstance<T>(strServiceUrl,null);  
  119.        }  
  120.        /// <summary>  
  121.        /// 返回设置中名子为bindingName的Uri  
  122.        /// </summary>  
  123.        /// <param name="bindingName"></param>  
  124.        /// <returns></returns>  
  125.        public static Uri GetEndpointAddress(string bindingName)  
  126.        {  
  127.            var client = WCFConfigHelper.GetChannelEndpointElement(bindingName,false);  
  128.            if(client!=null)  
  129.            {  
  130.                return client.Address;  
  131.            }  
  132.            return null;  
  133.        }  
  134.        /// <summary>  
  135.        /// 创建一个WCF服务实例  
  136.        /// </summary>  
  137.        /// <typeparam name="T"></typeparam>  
  138.        /// <param name="strServiceUrl">WCF Service Url</param>  
  139.        /// <param name="host">(127.0.0.1)</param>  
  140.        /// <param name="port">1-65535</param>  
  141.        /// <param name="bindingName">设置中Binding的名子</param>  
  142.        /// <returns>WCF服务实例</returns>  
  143.        /// <remarks></remarks>  
  144.        public static T GetInstance<T>(string strServiceUrl = null,string host = null,short port = 0,string bindingName = "COMM") where T : IDisposable, ICommunicationObject, new()  
  145.        {  
  146.            T _instance = default(T);  
  147.            string serviceUri = strServiceUrl;  
  148.   
  149.            object[] paras = new object[2];  
  150.            BasicHttpBinding binding = new BasicHttpBinding(BasicHttpSecurityMode.None);  
  151.   
  152.            //返回设置  
  153.            var bindConfig = WCFConfigHelper.GetBasicHttpBindingElement(bindingName, true);  
  154.            bindConfig.ApplyConfiguration(binding);//应用设置  
  155.   
  156.            EndpointAddress address;  
  157.            if (serviceUri == null)//从设置中返回URL  
  158.            {  
  159.                var client = WCFConfigHelper.GetChannelEndpointElement(bindingName, true);  
  160.                var endpoint = client.Address;  
  161.                string url = string.Format(endpoint.ToString(), GetServerName<T>());  
  162.                Uri temp = new Uri(url);  
  163.                Uri newUri = temp;  
  164.                if (host != null)//如果输入参数中有HOST,则替换源设置中的HOST及端口  
  165.                {  
  166.                    if (port == 0) port = 80;  
  167.                    newUri = new Uri(string.Format("http://{0}:{1}{2}", host, port, temp.PathAndQuery));  
  168.                }  
  169.                //WCF访问地址  
  170.                address = new EndpointAddress(newUri);  
  171.            }  
  172.            else  
  173.            {  
  174.                address = new EndpointAddress(strServiceUrl);  
  175.            }  
  176.            //WCF设置及WCF地址  
  177.            paras[0] = binding;  
  178.            paras[1] = address;  
  179.   
  180.            ConstructorInfo constructor;  
  181.   
  182.            try  
  183.            {  
  184.                Type[] types = new Type[2];  
  185.                types[0] = typeof(Binding);  
  186.                types[1] = typeof(EndpointAddress);                  
  187.                constructor = typeof(T).GetConstructor(types);//声明调用哪个构造  
  188.            }  
  189.            catch (Exception)  
  190.            {  
  191.                return _instance;  
  192.            }  
  193.   
  194.            if (constructor != null)  
  195.                _instance = (T)constructor.Invoke(paras);//调用构造生成WCF访问类  
  196.   
  197.            return _instance;  
  198.        }  
  199.   
  200.        /// <summary>  
  201.        /// 根据CLIENT返回接口类型名子,  
  202.        /// </summary>  
  203.        /// <typeparam name="T"></typeparam>  
  204.        /// <returns></returns>  
  205.        private static string GetServerName<T>()  
  206.        {  
  207.            Type t = typeof (T);  
  208.            var interFace =  
  209.                t.GetInterfaces().FirstOrDefault(w => w.IsDefined(typeof (ServiceContractAttribute), false));  
  210.   
  211.            if (interFace != null)  
  212.            {  
  213.                return interFace.Name;  
  214.            }  
  215.            return "";  
  216.        }  
  217.    }  
  1. 读取设置类  
  1.   
  1. /// <summary>  
  2.     /// 读取WCF设置  
  3.     /// </summary>  
  4.     public static class WCFConfigHelper  
  5.     {  
  6.         #region Section  
  7.           
  8.         /// <summary>  
  9.         /// 返回Bindings设置  
  10.         /// </summary>  
  11.         /// <returns></returns>  
  12.         public static BindingsSection GetBindingsSection()  
  13.         {  
  14.             return ConfigurationManager.GetSection("system.serviceModel/bindings"as BindingsSection;  
  15.         }  
  16.         /// <summary>  
  17.         /// 返回ServicesSection设置  
  18.         /// </summary>  
  19.         /// <returns></returns>  
  20.         public static ServicesSection GetServicesSection()  
  21.         {  
  22.             return ConfigurationManager.GetSection("system.serviceModel/services"as ServicesSection;  
  23.         }  
  24.         /// <summary>  
  25.         /// 返回BehaviorsSection设置  
  26.         /// </summary>  
  27.         /// <returns></returns>  
  28.         public static BehaviorsSection GetBehaviorsSection()  
  29.         {  
  30.             return ConfigurationManager.GetSection("system.serviceModel/behaviors"as BehaviorsSection;  
  31.         }  
  32.         /// <summary>  
  33.         /// 返回ClientSection设置  
  34.         /// </summary>  
  35.         /// <returns></returns>  
  36.         public static ClientSection GetClientSection()  
  37.         {  
  38.             return ConfigurationManager.GetSection("system.serviceModel/client"as ClientSection;  
  39.         }  
  40.         #endregion  
  41.  
  42.         #region Binding  
  43.         /// <summary>  
  44.         /// 返回BasicHttpBinding设置  
  45.         /// </summary>  
  46.         /// <returns></returns>  
  47.         public static BasicHttpBindingElement GetBasicHttpBindingElement(string name,bool returnDefault)  
  48.         {  
  49.             var list = GetBindingsSection().BasicHttpBinding.Bindings.Cast<BasicHttpBindingElement>();  
  50.             var re = list.FirstOrDefault(w => w.Name == name);  
  51.             if (re == null && returnDefault) re = list.FirstOrDefault();  
  52.             return re;  
  53.         }  
  54.         /// <summary>  
  55.         /// 返回NetTcpBindingElement设置  
  56.         /// </summary>  
  57.         /// <returns></returns>  
  58.         public static NetTcpBindingElement GetNetTcpBindingElement(string name,bool returnDefault)  
  59.         {  
  60.             var list = GetBindingsSection().NetTcpBinding.Bindings.Cast<NetTcpBindingElement>();  
  61.             var re = list.FirstOrDefault(w => w.Name == name);  
  62.             if (re == null && returnDefault) re = list.FirstOrDefault();  
  63.             return re;  
  64.         }  
  65.         /// <summary>  
  66.         /// 返回WSHttpBindingElement设置  
  67.         /// </summary>  
  68.         /// <returns></returns>  
  69.         public static WSHttpBindingElement GetWSHttpBindingElement(string name, bool returnDefault)  
  70.         {  
  71.             var list = GetBindingsSection().WSHttpBinding.Bindings.Cast<WSHttpBindingElement>();  
  72.             var re = list.FirstOrDefault(w => w.Name == name);  
  73.             if (re == null && returnDefault) re = list.FirstOrDefault();  
  74.             return re;  
  75.         }  
  76.         #endregion  
  77.  
  78.         #region Behaviors  
  79.   
  80.         /// <summary>  
  81.         /// 返回ServiceBehaviorElement设置  
  82.         /// </summary>  
  83.         /// <returns></returns>  
  84.         public static ServiceBehaviorElement GetServiceBehaviorElement(string name, bool returnDefault)  
  85.         {  
  86.             var list = GetBehaviorsSection().ServiceBehaviors.Cast<ServiceBehaviorElement>();  
  87.             var re = list.FirstOrDefault(w => w.Name == name);  
  88.             if (re == null && returnDefault) re = list.FirstOrDefault();  
  89.             return re;  
  90.         }  
  91.         #endregion  
  92.   
  93.         /// <summary>  
  94.         /// 返回设置是的ChannelEndpointElement  
  95.         /// </summary>  
  96.         /// <param name="name"></param>  
  97.         /// <param name="returnDefault"></param>  
  98.         /// <returns></returns>  
  99.         public static ChannelEndpointElement GetChannelEndpointElement(string name, bool returnDefault)  
  100.         {  
  101.             var list = GetClientSection().Endpoints.Cast<ChannelEndpointElement>();  
  102.                   
  103.             var re = list.FirstOrDefault(w => w.Name == name);  
  104.             if (re == null && returnDefault) re = list.FirstOrDefault();  
  105.             return re;  
  106.         }  
  107.     }  


使用方法

 

  1. #region 通用Execute  
  2.   
  3.         /// <summary>  
  4.         /// 使用设置接口设置执行WCF(默认接口设置为COMM)  
  5.         /// </summary>  
  6.         /// <typeparam name="TClient">WCF客户端代理</typeparam>  
  7.         /// <param name="port">设置WCF服务的端口号</param>  
  8.         /// <param name="action">要执行WCF的方法</param>  
  9.         /// <param name="host">设置WCF服务的服务器名称或IP</param>  
  10.         public static void Execute<TClient>(string host = nullshort port = 0, Action<TClient> action = null)  
  11.                 where TClient : class, IDisposable, ICommunicationObject, new()  
  12.         {  
  13.             Execute(null"COMM", host, port, action);  
  14.         }  
  15.   
  16.         /// <summary>  
  17.         /// 执行WCF  
  18.         /// </summary>  
  19.         /// <typeparam name="TClient">服务Client类型</typeparam>  
  20.         /// <param name="strServiceUrl">服务URL(如果为空,则从web.Config中读取名子为COMM的URL)</param>  
  21.         /// <param name="binding">设置中Binding的名子.</param>  
  22.         /// <param name="port">设置WCF服务的端口号</param>  
  23.         /// <param name="exceptionAction">调用WCF错误时执行的方法</param>  
  24.         /// <param name="action">要执行服务的方法列表</param>  
  25.         /// <param name="host">设置WCF服务的服务器名称或IP</param>  
  26.         /// <remarks></remarks>  
  27.         public static void Execute<TClient>(string strServiceUrl = nullstring binding = nullstring host = null,  
  28.                                       short port = 0, Action<Exception> exceptionAction = null, Action<TClient> action = null)  
  29.                 where TClient : IDisposable, ICommunicationObject, new()  
  30.         {  
  31.             WcfServiceFactory.Execute(strServiceUrl, binding, host, port, exceptionAction, action);  
  32.         }  
  33.   
  34.         /// <summary>  
  35.         ///   
  36.         /// </summary>  
  37.         /// <param name="strServiceUrl"></param>  
  38.         /// <param name="binding"></param>  
  39.         /// <param name="host"></param>  
  40.         /// <param name="port"></param>  
  41.         /// <param name="action"></param>  
  42.         /// <typeparam name="TClient"></typeparam>  
  43.         public static void Execute<TClient>(string strServiceUrl = nullstring binding = nullstring host = null,  
  44.                                       short port = 0, Action<TClient> action = null)  
  45.                 where TClient : IDisposable, ICommunicationObject, new()  
  46.         {  
  47.             Execute(strServiceUrl, binding, host, port, null, action);  
  48.         }  
  49.         #endregion  
  50.  
  51.         #region 通用ExecuteReturn  
  52.         /// <summary>  
  53.         ///   
  54.         /// </summary>  
  55.         /// <typeparam name="TClient">服务Client类型</typeparam>  
  56.         /// <typeparam name="TResult">执行WCF服务的返回数据类型</typeparam>  
  57.         /// <param name="strServiceUrl">设置WCF服务的地完整地址</param>  
  58.         /// <param name="binding">设置中Binding的名子.</param>  
  59.         /// <param name="host">设置WCF服务的服务器名称或IP</param>  
  60.         /// <param name="port">设置WCF服务的端口</param>  
  61.         /// <param name="exceptionAction"></param>  
  62.         /// <param name="action">要执行WCF的方法</param>  
  63.         /// <returns></returns>  
  64.         public static TResult ExecuteReturn<TClient, TResult>(string strServiceUrl = nullstring binding = null,  
  65.                                                               string host = nullshort port = 0,  
  66.                                                               Action<Exception> exceptionAction = null,  
  67.                                                               Func<TClient, TResult> action = null)  
  68.                 where TClient : IDisposable, ICommunicationObject, new()  
  69.         {  
  70.             return WcfServiceFactory.ExecuteReturn(strServiceUrl, binding, host, port, exceptionAction, action);  
  71.         }  
  72.         #endregion  

添加配置,aaa无用,但必须设置,COMM在调用时使用,{0}为服务名,自动匹配

  1. <endpoint address="http://localhost:1234/Services/{0}.svc" binding="basicHttpBinding"  
  2.         contract="aaa" name="COMM" />  
  1. <basicHttpBinding>  
  2.         <binding name="AAA" closeTimeout="00:01:00" openTimeout="00:01:00"  
  3.           receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false"  
  4.           bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"  
  5.           maxBufferSize="96553600" maxBufferPoolSize="52428800" maxReceivedMessageSize="96553600"  
  6.           messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"  
  7.           useDefaultWebProxy="true">  
  8.           <readerQuotas maxDepth="3200" maxStringContentLength="81920000"  
  9.             maxArrayLength="91638400" maxBytesPerRead="409600" maxNameTableCharCount="91638400" />  
  10.           <security mode="None">  
  11.             <transport clientCredentialType="None" proxyCredentialType="None"  
  12.               realm="" />  
  13.             <message clientCredentialType="UserName" algorithmSuite="Default" />  
  14.           </security>  
  15.         </binding>  
  16.       </basicHttpBinding>  
原文地址:https://www.cnblogs.com/weivyuan/p/2555844.html