当前位置: 移动技术网 > IT编程>开发语言>c# > 总结C#动态调用WCF接口的两种方法

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

2019年07月18日  | 移动技术网IT编程  | 我要评论
如何使用 1、第一种方式比较简单,而且也是大家喜欢的,因为不需要任何配置文件就可解决,只需知道服务契约接口和服务地址就可以调用。 2、使用invoke的方式,但是需

如何使用

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

总结

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

如您对本文有疑问或者有任何想说的,请 点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网