简体   繁体   English

WCF服务消耗

[英]WCF services consuming

I have two projects, one is a set of WCF services (let's call P1) and the other is a standard web application (P2). 我有两个项目,一个是一组WCF服务(我们称为P1),另一个是标准Web应用程序(P2)。

As a start, we have consumed P1 services in P2 as SOAP services and everything went fine. 首先,我们将P2中的P1服务用作SOAP服务,并且一切正常。 Later we noticed that in all of our project deployments, we are hosting both P1 & P2 on the same server. 后来我们注意到,在我们所有的项目部署中,我们都将P1和P2托管在同一服务器上。 So we thought why should we keep it like this - meaning: Why should we serialize/de-serialize the request/response every time for every method when it is running in the same server. 因此,我们想到了为什么要这样保持它的意思-意思是:为什么每次在同一服务器上运行的每个方法,我们都应该每次对请求/响应进行序列化/反序列化。 So we made a decision to use P1 as standard project library reference in P2. 因此,我们决定使用P1作为P2中的标准项目库参考。

We had to make a lot of modifications because the proxy class name changes and having to remove the client "close" method after each call. 我们必须进行大量修改,因为代理类名称发生了变化,并且每次调用后都必须删除客户端的“ close”方法。 Now, we have a new deployment that will requires P1 to be on a different server than P2, which we can change, and we have to consume P1 again as WCF service - meaning tons of changes all over the P2 and ending by having the serialization overhead on all of other deployments! 现在,我们有了一个新的部署,它将要求P1可以与P2放在不同的服务器上,并且可以更改,并且我们必须再次使用P1作为WCF服务-这意味着在P2上要进行大量更改,并通过序列化来结束所有其他部署的开销!

The question is, is there any way to make such a dynamic reference to P1, so no coding is required regardless the deployment is on 1 or 2 servers? 问题是,是否有任何方法可以动态引用P1,所以无论部署在1台或2台服务器上,都不需要编码?

It is possible to make a WCF service run local( project reference ) or as a service based on some key on the web.config. 可以使WCF服务在本地运行(项目参考),也可以作为基于web.config上某个键的服务运行。 I did the following example but I didnt test it but I have done exactly similar thing before 我做了下面的例子,但是我没有测试,但是之前我做过完全相似的事情

Add key in the web config say serviceMode="local/service" 在Web配置中添加密钥,说serviceMode =“ local / service”

Then say you have wcf service interface 然后说你有wcf服务接口

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

implementation 实作

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

///Now in your web application ///现在在您的Web应用程序中

you will have 您将拥有

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

    }

Now how you use it 现在如何使用它

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

Note: Define your interfaces and data contracts in a separate assembly so that you can share it with the web application that needs wcf run as a service. 注意:在单独的程序集中定义接口和数据协定,以便可以与需要wcf作为服务运行的Web应用程序共享它们。

All your components in P2 which consume services from P1 should only consume the service interface (ie IMyService , ISomeOtherService ). P2中所有使用P1服务的组件都应仅使用服务接口(即IMyServiceISomeOtherService )。 They should not care whether it is a local instance or a proxy and neither should they close the connection. 他们不必在乎它是本地实例还是代理,也不应该关闭连接。

The easiest (imho) to realize this is by using dependency injection through an IoC like Castle Windsor (it's the only one I'm vaguely familiar with but there are several others out there). 实现这一点的最简单(恕我直言)是通过像温莎城堡(Castle Windsor)这样的IoC使用依赖注入(这是我所不熟悉的唯一一个,但还有其他几个)。 The container will be responsible to provide instances of the service interfaces. 容器将负责提供服务接口的实例。 You can provide different implementations and configure the container at runtime with the appropriate one (WCF service or local instance). 您可以提供不同的实现,并在运行时使用适当的实现(WCF服务或本地实例)配置容器。 The container will also be responsible for disposing of the service components once they are not required anymore (ie calling Close() on the WCF proxies and doing nothing for the others). 一旦不再需要这些服务组件,容器还将负责处理这些服务组件(即,在WCF代理上调用Close() ,对其他组件则不执行任何操作)。

It's a big topic so I'd suggest you search the internet for some of the keywords - there is lot of material out there. 这是一个很大的话题,所以我建议您在互联网上搜索一些关键字-那里有很多资料。

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

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