0

私は 2 つのプロジェクトを持っています。1 つは WCF サービスのセット (P1 と呼びましょう) で、もう 1 つは標準 Web アプリケーション (P2) です。

まず、P2 で P1 サービスを SOAP サービスとして使用しましたが、すべてうまくいきました。後で、すべてのプロジェクト展開で、同じサーバーで P1 と P2 の両方をホストしていることに気付きました。つまり、同じサーバーで実行されているすべてのメソッドに対して、毎回要求/応答をシリアル化/逆シリアル化する必要があるのはなぜですか。そのため、P1 を P2 の標準プロジェクト ライブラリ リファレンスとして使用することにしました。

プロキシ クラス名が変更され、呼び出しごとにクライアントの "close" メソッドを削除する必要があったため、多くの変更を行う必要がありました。これで、P1 が P2 とは別のサーバー上にある必要がある新しい展開ができました。これは変更可能であり、P1 を WCF サービスとして再度使用する必要があります。つまり、P2 全体で大量の変更が行われ、シリアル化によって終了します。他のすべてのデプロイメントのオーバーヘッド!

問題は、P1 へのこのような動的な参照を作成する方法があるので、1 台または 2 台のサーバー上に配置されているかどうかに関係なく、コーディングは必要ないということです。

4

2 に答える 2

2

WCF サービスをローカル (プロジェクト参照) で実行するか、web.config のキーに基づいてサービスとして実行することができます。次の例を実行しましたが、テストはしませんでしたが、以前にまったく同じことをしました

serviceMode="local/service" と言う Web 構成にキーを追加します。

次に、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 アプリケーションと共有できるように、別のアセンブリでインターフェイスとデータ コントラクトを定義します。

于 2013-09-06T23:24:25.777 に答える