好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

总结C#动态调用WCF接口的两种方法

如何使用

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

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

客户端调用DEMO

?

//第一种方式

string url = "http://localhost:3000/DoubleService.svc" ;

IDoubleService proxy = WcfInvokeFactory.CreateServiceByUrl<IDoubleService>(url);

int result = proxy.Add(1, 3);

 

 

//第二种方式<br><br>int result1 = WCFInvoke.Invoke(t => t.Add(1, 3));<br><br>

<system.serviceModel>

   <behaviors>

    <endpointBehaviors>

     <behavior name= "NewBehavior" >

      <dataContractSerializer maxItemsInObjectGraph= "65536000" />

     </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= "2147483647"

         maxBufferPoolSize= "524288"

         maxReceivedMessageSize= "2147483647" >

      <readerQuotas maxDepth= "128" maxStringContentLength= "2147483647" maxArrayLength= "16384" maxBytesPerRead= "4096" maxNameTableCharCount= "16384" />

     </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 = 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

   {

     /// <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 < 1))

       {

         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 == 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();

         }

       }

     }

   }

总结

第一种方式比较常见,第二种方式是我参考另外一个项目中的写法,其中的有一些细节我还没有搞明白,实现了这个功能后还需要再看看这部分代码,再消化消化。以上就是这篇文章的全部内容,希望能给大家带来一定的帮助,如果有疑问大家可以留言交流。

原文链接:http://HdhCmsTestcnblogs测试数据/sword-successful/p/4760376.html

dy("nrwz");

查看更多关于总结C#动态调用WCF接口的两种方法的详细内容...

  阅读:52次