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

4 篇文章 0 订阅

写一个类,用于动态生成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>



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值