Web サービスから返されたオブジェクトに直接バインドする必要がありますか?それとも、クライアント側のオブジェクトをグリッド コントロールにバインドする必要がありますか? たとえば、オブジェクト Car を返すサービスがある場合、Web サービスの Car オブジェクトから値を入力するクライアント側の Car オブジェクトを用意する必要がありますか? ベストプラクティスと見なされるものは何ですか? C# では、クラスをシリアライズ可能としてマークする必要がありますか、それとも特別なことをする必要がありますか?
5 に答える
これは良い質問です。これは、私が自問した 2 つの質問と同じ行に従います。
どちらも一読の価値があるかもしれません。
Heres 私の 2 つのビット:
- 可能な場合は、Web サービスの戻り値の型をプリミティブに保つようにしてください。これにより、メッセージのサイズが縮小されるだけでなく、受信側での複雑さも軽減されます。
- 複雑なオブジェクトを返す必要がある場合は、生の xml 文字列として返します(以下で説明します)。
次に、オブジェクトを表し、その xml を処理する別のクラスを作成します。クラスを xml から簡単にインスタンス化し、xml にシリアル化できるようにします。その後、両方のプロジェクト (Web サービスとクライアント) は具象オブジェクトを使用して DLL を参照できますが、プロキシ クラスとの厄介な結合はありません。この結合により、コードを共有している場合に問題が発生します。
例(Car
クラスを使用):
- Web Service (
CarFactory
) メソッドBuyCar(string make, string model)
は、車を返すファクトリ メソッドです。 - また、オブジェクトを修復するため
Mechanic
にオブジェクトに作用するクラスを作成しCar
ます。これは、Web サービスの知識なしで開発されます。 Garage
次に、アプリケーションのクラスを権利化します。CarFactory
サービスにWeb 参照を追加して車を入手Mechanic
し、ガレージに を追加してから、ナックルを鳴らして、工場から車を入手して作業する準備をします。- 次に、結果を取得してコンパイラにうめき声
CarFactory.BuyCar("Audi", "R8")
を伝えると、すべてが失敗します。これは、実際には元の型ではないためです。Mechanic.Inspect(myAudi)
Car
CarFactory.Car
Car
だから、私が提案した方法を使用して:
Car
独自の DLL でクラスを作成します。インスタンス化するメソッドを追加し、XML との間でそれぞれシリアル化します。- Web サービスを作成
CarFactory
し、DLL への参照を追加し、前と同じように車を作成しますが、オブジェクトを返す代わりに XMLを返します。 - 、DLL、およびWeb サービス
Garage
への参照を追加して作成します。メソッドを呼び出すと、文字列が返されます。次に、この文字列をクラスに渡し、オブジェクト モデルを再構築します。すべてが同じ賛美歌シート (または DLL?) から歌われているため、 もこれらに喜んで取り組むことができます :)Mechanic
Car
CarFactory
BuyCar
Car
Mechanic
Car's
- 主な利点の 1 つは、オブジェクトの設計が変更された場合、DLL を更新するだけで済み、Web サービスとクライアント アプリがプロセスから完全に分離されることです。
注:多くの場合、 Facadeレイヤーを作成して、Web サービスと連携し、XML 結果からオブジェクトを自動生成すると便利です。
それが理にかなっていることを願っています。そうでない場合は、叫んでください。明確にします。
これは、実際にはWebサービスから何を取得しているかによって異なります。それらが単純なデータ転送オブジェクトであり、データのみを表示している場合は、はい、バインドできます。オブジェクトを編集する場合は、変更を追跡する必要があるため、役に立たない場合があります。
クライアント上のオブジェクトやコレクションは変更を追跡しますか?もしそうなら、あなたはそれらを使うことができます。
変更の追跡がない場合は、自分で変更を追跡する必要があるため、オブジェクトを変換するか、何かでラップして変更を追跡する必要があります。
繰り返しになりますが、実際には、何を取得しているか、何をサポートしているか、何をしているか、およびサーバーが変更に対してどのような応答を求めているかによって異なります。
できることの 1 つは、必要な追加機能を備えた Web サービス データ コントラクトに対応するクライアント クラスを作成し、Web サービス参照を設定して既存の型を再利用することです。その場合、バインドする追加のラッパー クラスを作成する理由はありません。
Web サービスの種類に直接バインドすると、カップリングが導入されます。将来、Web サービスが変更された場合、多くのコード変更を意味する望ましくない副作用が生じる可能性があります。
たとえば、今日は .asmx Web サービスを使用していて、明日は WCF に移行する場合はどうでしょうか。WCF がシリアル化しない型を使用している場合、コードにかなりの変更が加えられる可能性があります。
多くの場合、長期的には、特定のクライアント側オブジェクトを作成してから、Web サービスのデータ コントラクト型との間で変換する方が適切です。大変な作業に思えるかもしれませんが、変更が 1 か所にローカライズされるため、リファクタリングの時期になると、多くの場合、これが大幅に報われます。
Web サービスとクライアントの両方の所有者である場合。
また、Web サービス呼び出しのパラメーターを、データだけでなく動作 (実際のコード化されたロジック) も含む複雑なクラスにする必要がある場合、Web サービス フレームワークを使用してこれらの Web サービスを開発するときに、少し困ったことになります。Rob Cooper
の回答で示唆されているように、純粋な xml を Web サービス パラメーターおよび xml シリアル化として使用できますが、よりクリーンなソリューションがあります。
Visual Studio 2005 を使用している場合 (おそらく 2008 にも同じことが当てはまります)、次の記事で説明されているように、VS がプロキシを作成する方法をカスタマイズできます:
Visual Studio 2005 で生成された Web サービス プロキシをカスタマイズする
このようにして、プロキシ クラスを生成する代わりに独自のクラスを使用するように VS に指示できます。
考えてみると、Rob Cooper によって提案されたのとほとんど同じソリューションですが、少しひねりを加えて、Facade レイヤーを自分で作成するのではなく、VS 自体をこのレイヤーとして使用します。