0

次のVisualStudioプロジェクト構造を検討してください

  • ProjectA.csproj
    • AClass.cs
  • ProjectB.csproj
    • 参考文献
      • ProjectA
    • Webリファレンス
      • AWebService
  • AWebService.csproj
    • 参考文献
      • ProjectA
    • ReturnAClassViaWebService.asmx

この問題は、ProjectBがWeb参照をAWebServiceに追加し、AClassの新しい実装を含むAWebServiceにアクセスするためのすべてのプロキシコードを自動的に生成するときに発生します。他のすべてのコードはProjectAで定義されたAClassを使用する必要があるため、サービスから返されたAWebService.AClassを使用可能なものに変換する必要があります。

現在、2つのソリューションを検討していますが、どちらも理想的ではありません。

  • 生成されたReference.csを手動で編集して、AClassの新しい定義を削除します
  • AWebService.AClassをストリームにシリアル化してから、ProjectA.AClassに逆シリアル化します。

誰かがより良い解決策を持っていますか?これは、他の開発者が経験したことのある一般的なもののようです。

理想的には、まったく新しい実装を生成するのではなく、ProjectBで生成されたプロキシコードでProjectA.AClassを参照する必要があります。

私たちの環境は、.NET2.0を使用したVS2008です。

4

3 に答える 3

2

私はあなたが説明しているのと同じ問題を抱えており、あなたが指定した両方のオプションを試しましたが、どちらにも完全に満足することはありませんでした。

私たち両方がこの問題を抱えている理由は、少なくとも部分的には、共有ライブラリーとコンシューマーとプロバイダーのWebサービスソリューションが、 Webサービス設計で受け入れられているパターンと慣行に違反しているためです。コンシューマー側では、WSDLで公開されているインターフェースを知っていれば十分です。

それでも、WebサービスプロバイダーとWebサービスコンシューマーの間の緊密な結合を受け入れる準備ができていて、現在のクライアントが別のクライアント(共有ライブラリを参照できない可能性がある)に置き換えられないことが確実である場合は、次に、提案されたソリューションがアプリを構造化するための優れた方法のように見える理由を理解しました。重要な注意:これらの質問の両方に本当に正直に「はい」と答えることができますか?おそらくそうではありません。

要点をまとめると:

  1. この問題は、ある種の共有ライブラリ(クライアントとサーバーの両方で使用される)で定義されたクラス(たとえば、強く型付けされたデータセット)がある場合に発生します。
  2. 一部の共有クラスは、Webサービスによって定義されたインターフェースで使用されます。
  3. Web参照が追加されると、Web参照名前空間内に(共有クラス用に)定義されたプロキシクラスがあります。
  4. 名前空間が異なるため、プロキシクラスと共有ライブラリ内の実際の対応するクラスには互換性がありません。

共有ライブラリのセットアップを続行する場合に試すことができる4つの解決策を次に示します。

  1. しないでください。クライアント側でプロキシクラスを使用します。これは、それが行われることを意図している方法です。WebサービスWSDLによって公開されていない共有ライブラリの側面を同時に活用したい場合を除いて、正常に機能します。
  2. クラスの提供されたコピー/複製機能を実装または使用します(たとえば、強い型のデータセットを別のデータセットにMerge()しようとすることができます)。キャストは明らかに不可能であり、コピーオプションは、望ましくない副作用をもたらす傾向があるため、通常はあまり良い解決策ではありません。たとえば、データセットを別のデータセットにマージすると、ターゲットデータセットのすべての行に「変更済み」というラベルが付けられます。これはAcceptChanges()で復活させることができますが、受信した行のいくつか実際に変更された場合はどうなりますか。
  3. 基本データ型を除くすべてを文字列にシリアル化します(そして再びコンシューマー側に戻します)。型安全性の喪失は、このアプローチの重要な弱点の1つです。
  4. Reference.cs内の共有クラスの明示的な宣言を削除し、Reference.cs内で言及されている場所で共有クラスから名前空間を削除します。これはおそらく最良のオプションです。あなたは本当に欲しいものを手に入れます。共有クラスはWebサービスによって返されます。このソリューションの唯一の苛立たしい欠点は、Web参照を更新するたびにreference.csファイルへの変更が失われることです。私を信じてください:それはひどく迷惑になることがあります。

同様の議論へのリンクは次のとおりです。

于 2011-03-16T22:43:13.357 に答える
0

[サービス参照の追加]フォームの[詳細]ボタンをクリックすると、クライアントとサービスの間で既存の参照タイプを再利用できます。[参照されるアセンブリでタイプを再利用する]チェックボックスがオンになっていることを確認し、サービスクライアントが生成されるときに、プロジェクトAのすべてのタイプを再利用する必要があります。

以前のバージョンでは、これは常に正しく機能するとは限らず、[指定された参照アセンブリでタイプを再利用する]オプションを選択し、リストボックスで適切なアセンブリをチェックして、共有タイプのアセンブリを明示的に選択する必要がありました。ただし、これをVS 2008 SP1でテストしたところ、期待どおりに機能しているようです。明らかに、サービスプロジェクトとクライアントプロジェクトで使用されているタイプが両方ともプロジェクトAのものであることを確認する必要があります。

これがお役に立てば幸いです。

于 2011-03-11T18:48:17.213 に答える
-1

私たちのプロジェクトの1つで同様の問題が発生しました。いくつかの依存関係があったため、プロジェクト1にはプロジェクト2のオブジェクトが必要だったため、循環参照を作成することになりましたが、プロジェクト1に依存してビルドされたプロジェクト3の前にプロジェクト2をビルドできませんでした。

この問題を解決するために、両方のプロジェクトからすべてのパブリックスタンドアロンクラスを抽出し、それらを単一のライブラリ内に配置しました。最終的に、次のようなものを作成しました。

  • Framework.Objects
  • Framework.Interface
  • Framework.Implementation
  • ウェブサービス

この場合、WebServiceはすべてのプロジェクトにリンクされますが、外部の関係者は、操作するオブジェクトとインターフェイスクラスにのみリンクします。実際の実装は、実行時にリフレクションを介して結合されました。

お役に立てれば

于 2011-03-08T08:29:21.050 に答える