繁体   English   中英

WCF服务消耗

[英]WCF services consuming

我有两个项目,一个是一组WCF服务(我们称为P1),另一个是标准Web应用程序(P2)。

首先,我们将P2中的P1服务用作SOAP服务,并且一切正常。 后来我们注意到,在我们所有的项目部署中,我们都将P1和P2托管在同一服务器上。 因此,我们想到了为什么要这样保持它的意思-意思是:为什么每次在同一服务器上运行的每个方法,我们都应该每次对请求/响应进行序列化/反序列化。 因此,我们决定使用P1作为P2中的标准项目库参考。

我们必须进行大量修改,因为代理类名称发生了变化,并且每次调用后都必须删除客户端的“ close”方法。 现在,我们有了一个新的部署,它将要求P1可以与P2放在不同的服务器上,并且可以更改,并且我们必须再次使用P1作为WCF服务-这意味着在P2上要进行大量更改,并通过序列化来结束所有其他部署的开销!

问题是,是否有任何方法可以动态引用P1,所以无论部署在1台或2台服务器上,都不需要编码?

可以使WCF服务在本地运行(项目参考),也可以作为基于web.config上某个键的服务运行。 我做了下面的例子,但是我没有测试,但是之前我做过完全相似的事情

在Web配置中添加密钥,说serviceMode =“ local / service”

然后说你有wcf服务接口

    [ServiceContract]
    public class ICalculator
    {
         [OperationContract]
        int Add(int x, int y);
    }

实作

  public class Calculator
   {
      public int Add(int x, y)
      {
        return x+y;
      }
}

///现在在您的Web应用程序中

您将拥有

   public LocalProxy:ICalculator //this will use direct instance of the Calculator Service
   {
      private ICalculator _calculator

      public  LocalProxy(ICalculator calculator)
      {
        _calculator =calculator;
      }

      public int Add(int x, int y)
      {
         return _calculator.Add(x,y);
      }

}




 public class RemoteProxy:ICalculator  ///This will be real wcf proxy

    {


       public int Add (int x,int y)
       {

          var endpointAddress = new EndpointAddress(EndpointUrl);
           ChannelFactory<ICalculator> factory = null;
           ICalculator calculator ;

          try
          {
             // Just picking a simple binding here to focus on other aspects
             Binding binding = new BasicHttpBinding();

             factory = new ChannelFactory<ICalculator>(binding);
             calculator= factory.CreateChannel(endpointAddress);
             if (calculator== null)
             {
                 throw new CommunicationException(
                    String.Format("Unable to connect to service at {0}", endpointUrl));
             }

             int sum= calculator.Add(x,y);
             ((IClientChannel)calculator).Close();

             calculator = null;
             factory.Close();
             factory = null;

             return sum;
          }
          finally
          {
             if (calculator!= null) ((IClientChannel)calculator).Close();
             if (factory != null) factory.Abort();
          }
       }

    }

现在如何使用它

 ICalculator _calculatorProxy;

    //get the web config key here, you may use strategy pattern to select between the two proxies


     if(key=="local)
    {
     _calculator= new LocalProxy(new Calculator)
    }
    else
    {
     _calculator= new RemoteProxy();
    }


    //then 
     _calculator.Add(3,5);

注意:在单独的程序集中定义接口和数据协定,以便可以与需要wcf作为服务运行的Web应用程序共享它们。

P2中所有使用P1服务的组件都应仅使用服务接口(即IMyServiceISomeOtherService )。 他们不必在乎它是本地实例还是代理,也不应该关闭连接。

实现这一点的最简单(恕我直言)是通过像温莎城堡(Castle Windsor)这样的IoC使用依赖注入(这是我所不熟悉的唯一一个,但还有其他几个)。 容器将负责提供服务接口的实例。 您可以提供不同的实现,并在运行时使用适当的实现(WCF服务或本地实例)配置容器。 一旦不再需要这些服务组件,容器还将负责处理这些服务组件(即,在WCF代理上调用Close() ,对其他组件则不执行任何操作)。

这是一个很大的话题,所以我建议您在互联网上搜索一些关键字-那里有很多资料。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM