您的位置:首页 > 其它

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>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: