C#动态调用WCF接口(2)
如何使用
1、第一种方式比较简单,而且也是大家喜欢的,因为不需要任何配置文件就可解决,只需知道服务契约接口和服务地址就可以调用。
2、使用Invoke的方式,但是需要在调用客户端配置WCF,配置后在Invoke类里封装服务契约接口即可。
//第一种方式
string url = "http://localhost:3000/DoubleService.svc";
IDoubleService proxy = WcfInvokeFactory.CreateServiceByUrl<IDoubleService>(url);
int result = proxy.Add(, ); //第二种方式
int result1 = WCFInvoke.Invoke(t => t.Add(, ));
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="NewBehavior">
<dataContractSerializer maxItemsInObjectGraph="" />
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IDoubleService"
closeTimeout="01:00:00"
openTimeout="01:00:00"
sendTimeout="01:00:00"
receiveTimeout="01:00:00"
maxBufferSize=""
maxBufferPoolSize=""
maxReceivedMessageSize="">
<readerQuotas maxDepth="" maxStringContentLength="" maxArrayLength="" maxBytesPerRead="" maxNameTableCharCount="" />
</binding>
</basicHttpBinding>
<netMsmqBinding>
<binding name="NetMsmqBinding_IAsyncSender">
<security mode="None" />
</binding>
</netMsmqBinding>
</bindings>
<client> <endpoint address="http://localhost:3000/DoubleService.svc"
binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_IDoubleService"
contract="DoubleStone.WebHost.IDoubleService"
name="BasicHttpBinding_IDoubleService" /> </client>
</system.serviceModel>
第一种调用方式
public class WcfInvokeFactory
{
#region WCF服务工厂
public static T CreateServiceByUrl<T>(string url)
{
return CreateServiceByUrl<T>(url, "basicHttpBinding");
} public static T CreateServiceByUrl<T>(string url, string bing)
{
try
{
if (string.IsNullOrEmpty(url)) throw new NotSupportedException("This url is not Null or Empty!");
EndpointAddress address = new EndpointAddress(url);
Binding binding = CreateBinding(bing);
ChannelFactory<T> factory = new ChannelFactory<T>(binding, address);
return factory.CreateChannel();
}
catch (Exception ex)
{
throw new Exception("创建服务工厂出现异常.");
}
}
#endregion #region 创建传输协议
/// <summary>
/// 创建传输协议
/// </summary>
/// <param name="binding">传输协议名称</param>
/// <returns></returns>
private static Binding CreateBinding(string binding)
{
Binding bindinginstance = null;
if (binding.ToLower() == "basichttpbinding")
{
BasicHttpBinding ws = new BasicHttpBinding();
ws.MaxBufferSize = ;
ws.MaxBufferPoolSize = ;
ws.MaxReceivedMessageSize = ;
ws.ReaderQuotas.MaxStringContentLength = ;
ws.CloseTimeout = new TimeSpan(, , );
ws.OpenTimeout = new TimeSpan(, , );
ws.ReceiveTimeout = new TimeSpan(, , );
ws.SendTimeout = new TimeSpan(, , ); bindinginstance = ws;
}
else if (binding.ToLower() == "nettcpbinding")
{
NetTcpBinding ws = new NetTcpBinding();
ws.MaxReceivedMessageSize = ;
ws.Security.Mode = SecurityMode.None;
bindinginstance = ws;
}
else if (binding.ToLower() == "wshttpbinding")
{
WSHttpBinding ws = new WSHttpBinding(SecurityMode.None);
ws.MaxReceivedMessageSize = ;
ws.Security.Message.ClientCredentialType = System.ServiceModel.MessageCredentialType.Windows;
ws.Security.Transport.ClientCredentialType = System.ServiceModel.HttpClientCredentialType.Windows;
bindinginstance = ws;
}
return bindinginstance; }
#endregion
}
第二种调用方式
public class WCFInvoke
{
/// <summary>
/// 你需要调用的服务契约
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="func"></param>
/// <returns></returns>
public static T Invoke<T>(Func<IDoubleService, T> func)
{
IServiceInvoker serviceInvoker=new WCFServiceInvoker();
return serviceInvoker.InvokeService(func);
}
} public interface IServiceInvoker
{
void InvokeService<T>(Action<T> invokeHandler) where T : class;
TReslt InvokeService<T, TReslt>(Func<T, TReslt> invokeHandler) where T : class;
} public class WCFServiceInvoker:IServiceInvoker
{
private static readonly ChannelFactoryManager FactoryManager = new ChannelFactoryManager(); private static readonly ClientSection ClientSection =
ConfigurationManager.GetSection("system.serviceModel/client") as ClientSection; public void InvokeService<T>(Action<T> invokeHandler) where T : class
{
KeyValuePair<string, string> endpointNameAddressPair = GetEndpointNameAddressPair(typeof(T));
var arg = FactoryManager.CreateChannel<T>(endpointNameAddressPair.Key, endpointNameAddressPair.Value);
var obj2 = (ICommunicationObject)arg;
try
{
invokeHandler(arg);
}
finally
{
try
{
if (obj2.State != CommunicationState.Faulted)
{
obj2.Close();
}
}
catch
{
obj2.Abort();
}
}
} public TReslt InvokeService<T, TReslt>(Func<T, TReslt> invokeHandler) where T : class
{
KeyValuePair<string, string> endpointNameAddressPair = GetEndpointNameAddressPair(typeof(T));
var arg = FactoryManager.CreateChannel<T>(endpointNameAddressPair.Key, endpointNameAddressPair.Value);
var obj2 = (ICommunicationObject)arg;
try
{
return invokeHandler(arg);
}
finally
{
try
{
if (obj2.State != CommunicationState.Closed || obj2.State != CommunicationState.Faulted)
{
obj2.Close();
}
}
catch
{
obj2.Abort();
}
}
} private KeyValuePair<string, string> GetEndpointNameAddressPair(Type serviceContractType)
{
var configException =
new ConfigurationErrorsException(
string.Format(
"No client endpoint found for type {0}. Please add the section <client><endpoint name=\"myservice\" address=\"http://address/\" binding=\"basicHttpBinding\" contract=\"{0}\"/></client> in the config file.",
serviceContractType));
if (((ClientSection == null) || (ClientSection.Endpoints == null)) || (ClientSection.Endpoints.Count < ))
{
throw configException;
}
foreach (ChannelEndpointElement element in ClientSection.Endpoints)
{
if (element.Contract == serviceContractType.ToString())
{
return new KeyValuePair<string, string>(element.Name, element.Address.AbsoluteUri);
}
}
throw configException;
}
}
public class ChannelFactoryManager : IDisposable
{
private static readonly Dictionary<Type, ChannelFactory> Factories = new Dictionary<Type, ChannelFactory>();
private static readonly object SyncRoot = new object(); public void Dispose()
{
Dispose(true);
} public virtual T CreateChannel<T>() where T : class
{
return CreateChannel<T>("*", null);
} public virtual T CreateChannel<T>(string endpointConfigurationName) where T : class
{
return CreateChannel<T>(endpointConfigurationName, null);
} public virtual T CreateChannel<T>(string endpointConfigurationName, string endpointAddress) where T : class
{
T local = GetFactory<T>(endpointConfigurationName, endpointAddress).CreateChannel();
((IClientChannel)local).Faulted += ChannelFaulted;
return local;
} protected virtual ChannelFactory<T> GetFactory<T>(string endpointConfigurationName, string endpointAddress)
where T : class
{
lock (SyncRoot)
{
ChannelFactory factory;
if (!Factories.TryGetValue(typeof(T), out factory))
{
factory = CreateFactoryInstance<T>(endpointConfigurationName, endpointAddress);
Factories.Add(typeof(T), factory);
}
return (factory as ChannelFactory<T>);
}
} private ChannelFactory CreateFactoryInstance<T>(string endpointConfigurationName, string endpointAddress)
{
ChannelFactory factory = null;
factory = !string.IsNullOrEmpty(endpointAddress) ? new ChannelFactory<T>(endpointConfigurationName, new EndpointAddress(endpointAddress)) : new ChannelFactory<T>(endpointConfigurationName); factory.Faulted += FactoryFaulted;
factory.Open();
return factory;
} private void ChannelFaulted(object sender, EventArgs e)
{
var channel = (IClientChannel)sender;
try
{
channel.Close();
}
catch
{
channel.Abort();
}
} private void FactoryFaulted(object sender, EventArgs args)
{
var factory = (ChannelFactory)sender;
try
{
factory.Close();
}
catch
{
factory.Abort();
}
Type[] genericArguments = factory.GetType().GetGenericArguments();
if ((genericArguments.Length == ))
{
Type key = genericArguments[];
if (Factories.ContainsKey(key))
{
Factories.Remove(key);
}
}
} protected virtual void Dispose(bool disposing)
{
if (disposing)
{
lock (SyncRoot)
{
foreach (Type type in Factories.Keys)
{
ChannelFactory factory = Factories[type];
try
{
factory.Close();
}
catch
{
factory.Abort();
}
}
Factories.Clear();
}
}
}
}
C#动态调用WCF接口(2)的更多相关文章
- C#动态调用WCF接口,两种方式任你选。
写在前面 接触WCF还是它在最初诞生之处,一个分布式应用的巨作. 从开始接触到现在断断续续,真正使用的项目少之又少,更谈不上深入WCF内部实现机制和原理去研究,最近自己做一个项目时用到了WCF. 从这 ...
- C#动态调用WCF接口
C#动态调用WCF接口 写在前面 接触WCF还是它在最初诞生之处,一个分布式应用的巨作. 从开始接触到现在断断续续,真正使用的项目少之又少,更谈不上深入WCF内部实现机制和原理去研究,最近自己做一个项 ...
- 动态调用wcf接口服务
1.url:http://localhost:8002/名称.svc/basic(.svc结尾) 2.需要引用的命名空间System.ServiceModel 3.调用代码: public class ...
- C#动态调用WCF接口(3)
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.S ...
- 动态调用WCF服务
动态调用WCF服务,只需要提供*.svc地址, 1:命名空间: using System.ServiceModel.Channels;using System.ServiceModel; 2:创建访问 ...
- 动态调用WCF
最近在做的一个项目中需要动态调用WCF地址,因为有很多终端服务器,而每台终端服务器上都部署一个WCF服务,中央服务器需要不定时调用其中某个或者多个WCF服务执行相关操作,因此添加引用及配置文件配置的方 ...
- 创建一个简单的WCF程序2——手动开启/关闭WCF服务与动态调用WCF地址
一.创建WCF服务器 1.创建WCF服务器的窗体应用程序 打开VS2010,选择文件→新建→项目菜单项,在打开的新建项目对话框中,依次选择Visual C#→Windows→Windows窗体应用程序 ...
- c# 动态调用WCF方法笔记!
//动态调用wcf方法 string url = "http://localhost:54379/ServiceWCF.svc"; IDoubleService proxy = W ...
- 动态调用WebService接口的几种方式
一.什么是WebService? 这里就不再赘述了,想要了解的====>传送门 二.为什么要动态调用WebService接口? 一般在C#开发中调用webService服务中的接口都是通过引用过 ...
随机推荐
- [BZOJ 1804] Flood
Link: BZOJ 1804 传送门 Solution: 不容易啊,第一道完全自己A掉的IOI题目..... 算法思想其实很简单: 模拟缩减的过程即可 将每条边转为2条有向边,每次找到最左边的边,沿 ...
- ios中将事件同步到系统日历
//获取日历事件 EKEventStore* eventStore = [[EKEventStorealloc] init]; NSDate* ssdate = [NSDatedateWithTime ...
- ios 多线程之NSThread篇举例详解
这篇博客是接着总篇iOS GCD NSOperation NSThread等多线程各种举例详解写的一个支篇.总篇也包含了此文的链接.本文讲解的知识点有NSThread的开始.取消.在当前线程执行任务. ...
- Android 架构 1.架构
项目分为了四个层级:模型层.接口层.核心层.界面层.模型层定义了所有的模型:接口层封装了服务器提供的API:核心层处理所有业务逻辑:界面层就处理界面的展示.几个层级之间的关系如下图所示: 层级关系:模 ...
- 【教训】 form表单提交时,action url中参数无效
今天提交一个表单,内容参考如下: <form action="add.php?a=123&b=456"> <input type="hi ...
- [ubuntu Setup] ubuntu 14.10 安装 JDK
from : http://www.cnblogs.com/plinx/archive/2013/06/01/3113106.html 1.到 Sun 的官网下载 http://www.oracle ...
- 常见Hibernate报错处理:出现“org.hibernate.QueryException: could not resolve property”和 is not mapped和could not locate named parameter错误的解决
正确写法: @Override @SuppressWarnings("unchecked") public List<Device> queryOSDevice(Str ...
- Yii添加验证码
添加带验证码的登陆: 1.先在模型modules下的LoginForm.php定义一个存储验证码的变量:public $verfyCode: 2.然后在rules()方法里定义:array('veri ...
- Python 自用代码(某方标准类网页源代码清洗)
用于mongodb中“标准”数据的清洗,数据为网页源代码,须从中提取: 标准名称,标准外文名称,标准编号,发布单位,发布日期,状态,实施日期,开本页数,采用关系,中图分类号,中国标准分类号,国际标准分 ...
- Java中的值传递与“引用传递”
首先,Java没有 引用传递 这么一说. Java仅仅有值传递.传递的都是值,基本数据类型传递的是值.引用类型传递的是地址值. 我来理一下这当中宛如米线跟米面绞在一起了,再跟粉丝混在一起的关系. 好的 ...