博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C#动态调用WCF接口,两种方式任你选。
阅读量:7102 次
发布时间:2019-06-28

本文共 8556 字,大约阅读时间需要 28 分钟。

写在前面

           接触WCF还是它在最初诞生之处,一个分布式应用的巨作。 从开始接触到现在断断续续,真正使用的项目少之又少,更谈不上深入WCF内部实现机制和原理去研究,最近自己做一个项目时用到了WCF。 从这个小项目中我学会了两个地方: 1、利用IIS部署WCF服务,也就是大家接触到的发布SVC文件。2、动态调用WCF接口。

           在这个项目中接触WCF时遇到的其实不仅仅是这两个问题,甚至连IIS支持SVC文件也让我折腾了好几把,IIS都重新卸载了两次。 我在这篇文章里用两种方式来实现。

 

如何使用

      1、第一种方式比较简单,而且也是大家喜欢的,因为不需要任何配置文件就可解决,只需知道服务契约接口和服务地址就可以调用。

      2、使用Invoke的方式,但是需要在调用客户端配置WCF,配置后在Invoke类里封装服务契约接口即可。

 

客户端调用DEMO

//第一种方式string url = "http://localhost:3000/DoubleService.svc";IDoubleService proxy = WcfInvokeFactory.CreateServiceByUrl
(url);int result = proxy.Add(1, 3);//第二种方式 int result1 = WCFInvoke.Invoke(t => t.Add(1, 3));

第一种调用方式

public class WcfInvokeFactory    {        #region WCF服务工厂        public static T CreateServiceByUrl
(string url) { return CreateServiceByUrl
(url, "basicHttpBinding"); } public static T CreateServiceByUrl
(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
factory = new ChannelFactory
(binding, address); return factory.CreateChannel(); } catch (Exception ex) { throw new Exception("创建服务工厂出现异常."); } } #endregion #region 创建传输协议 ///
/// 创建传输协议 /// ///
传输协议名称 ///
private static Binding CreateBinding(string binding) { Binding bindinginstance = null; if (binding.ToLower() == "basichttpbinding") { BasicHttpBinding ws = new BasicHttpBinding(); ws.MaxBufferSize = 2147483647; ws.MaxBufferPoolSize = 2147483647; ws.MaxReceivedMessageSize = 2147483647; ws.ReaderQuotas.MaxStringContentLength = 2147483647; ws.CloseTimeout = new TimeSpan(0, 30, 0); ws.OpenTimeout = new TimeSpan(0, 30, 0); ws.ReceiveTimeout = new TimeSpan(0, 30, 0); ws.SendTimeout = new TimeSpan(0, 30, 0); bindinginstance = ws; } else if (binding.ToLower() == "nettcpbinding") { NetTcpBinding ws = new NetTcpBinding(); ws.MaxReceivedMessageSize = 65535000; ws.Security.Mode = SecurityMode.None; bindinginstance = ws; } else if (binding.ToLower() == "wshttpbinding") { WSHttpBinding ws = new WSHttpBinding(SecurityMode.None); ws.MaxReceivedMessageSize = 65535000; ws.Security.Message.ClientCredentialType = System.ServiceModel.MessageCredentialType.Windows; ws.Security.Transport.ClientCredentialType = System.ServiceModel.HttpClientCredentialType.Windows; bindinginstance = ws; } return bindinginstance; } #endregion }

 

第二种调用方式

public class WCFInvoke    {        ///         /// 你需要调用的服务契约        ///         /// 
/// ///
public static T Invoke
(Func
func) { IServiceInvoker serviceInvoker=new WCFServiceInvoker(); return serviceInvoker.InvokeService(func); } }
public interface IServiceInvoker    {        void InvokeService
(Action
invokeHandler) where T : class; TReslt InvokeService
(Func
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
(Action
invokeHandler) where T : class { KeyValuePair
endpointNameAddressPair = GetEndpointNameAddressPair(typeof(T)); var arg = FactoryManager.CreateChannel
(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
(Func
invokeHandler) where T : class { KeyValuePair
endpointNameAddressPair = GetEndpointNameAddressPair(typeof(T)); var arg = FactoryManager.CreateChannel
(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
GetEndpointNameAddressPair(Type serviceContractType) { var configException = new ConfigurationErrorsException( string.Format( "No client endpoint found for type {0}. Please add the section
in the config file.", serviceContractType)); if (((ClientSection == null) || (ClientSection.Endpoints == null)) || (ClientSection.Endpoints.Count < 1)) { throw configException; } foreach (ChannelEndpointElement element in ClientSection.Endpoints) { if (element.Contract == serviceContractType.ToString()) { return new KeyValuePair
(element.Name, element.Address.AbsoluteUri); } } throw configException; } }
public class ChannelFactoryManager : IDisposable    {        private static readonly Dictionary
Factories = new Dictionary
(); private static readonly object SyncRoot = new object(); public void Dispose() { Dispose(true); } public virtual T CreateChannel
() where T : class { return CreateChannel
("*", null); } public virtual T CreateChannel
(string endpointConfigurationName) where T : class { return CreateChannel
(endpointConfigurationName, null); } public virtual T CreateChannel
(string endpointConfigurationName, string endpointAddress) where T : class { T local = GetFactory
(endpointConfigurationName, endpointAddress).CreateChannel(); ((IClientChannel)local).Faulted += ChannelFaulted; return local; } protected virtual ChannelFactory
GetFactory
(string endpointConfigurationName, string endpointAddress) where T : class { lock (SyncRoot) { ChannelFactory factory; if (!Factories.TryGetValue(typeof(T), out factory)) { factory = CreateFactoryInstance
(endpointConfigurationName, endpointAddress); Factories.Add(typeof(T), factory); } return (factory as ChannelFactory
); } } private ChannelFactory CreateFactoryInstance
(string endpointConfigurationName, string endpointAddress) { ChannelFactory factory = null; factory = !string.IsNullOrEmpty(endpointAddress) ? new ChannelFactory
(endpointConfigurationName, new EndpointAddress(endpointAddress)) : new ChannelFactory
(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 == 1)) { Type key = genericArguments[0]; 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(); } } } }

 

总结

      第一种方式比较常见,第二种方式是我参考另外一个项目中的写法,其中的有一些细节我还没有搞明白,实现了这个功能后还需要再看看这部分代码,再消化消化。由于是直接在项目中,所以没有提供源代码下载,有朋友需要的话我会整理出demo,稍后放出下载链接。

转载地址:http://rrdhl.baihongyu.com/

你可能感兴趣的文章
maven常见命令总结
查看>>
LightLife小组Alfha冲刺(第六天)
查看>>
U盘用FAT32还是用NTFS格式好
查看>>
Elasticsearch Java教程
查看>>
Python下使用help(dict),显示'more'不是内部或外部命令,也不是可运行的程序或批处理文件,该如何处理?...
查看>>
跟阿铭学Linux习题答案
查看>>
c#调用c++ dll(一)
查看>>
window install python easy_install
查看>>
字符串操作
查看>>
linux的命令补全(tab tab)
查看>>
题解 HDU1565 【方格取数(1)】
查看>>
题解 CF911D 【Inversion Counting】
查看>>
scikit-learn初步,一个KNN算法示例
查看>>
关于tableView的cell复用问题
查看>>
微博是个大金矿,使用VS2010编译QOAuth支持微博通用认证OAuth实现SINA微博“.NET研究”登陆...
查看>>
工信部通知要求加强域名系统安全保障工作
查看>>
How Digg is Built:讲述Digg背后的技术,互联网营销
查看>>
7款强大的Javascript网格插件推荐
查看>>
一起谈.NET技术,你是个软件架构师吗?
查看>>
JS小游戏
查看>>