WCFサービスからユーザー定義型をどのように返しますか?
-
22-07-2019 - |
質問
IISでホストされているWCFサービスがあります。クライアントが呼び出しを行い、別のプロジェクト/ dllで定義されているカスタムクラスを受け取ることを目的としています。 svcutil.exeを使用してサービスクライアントを生成しました。問題は、この自動生成されたクライアントに、サービスから返そうとしているクラスの新しい部分/プロキシ定義が含まれていることです。これで、コンパイル時に元のカスタムクラスと新しい部分定義の間で変換エラーがスローされます。では、WCFサービスからユーザー定義型をどのように返しますか?アドバイスありがとうございます。
解決
- はい、共有DLLへの参照を追加できます(生成されたプロキシクラスを使用するのではなく)
- はい、それはデータ契約の多くの意図を無効にします。また、何らかのカスタムシリアル化が行われている場合、サービスの拡張に問題があるかもしれません
私は以前にこの道を進んだことがあります。再拡張性/カスタムシリアル化-あなたは非常に注意する必要があります。 protobuf-net などの事前ロールシリアライザーを使用すると、少し簡単になりますWCFに直接統合でき、拡張性を考慮して設計されています)、簡単ではありません。
実際には、クラスを共有することの1つの利点は、テストが少し簡単になることです。どこにでも同じ IFoo
があるので、その IFoo
を適切な成功のチャンスとともに。プロキシが関与すると、モックを作成するのが難しくなります(テストコードと製品コードの間で移動する部分を変更する場合)。
他のヒント
サービスコールから返すタイプが DataContract
としてマークされていない場合、その同じアセンブリのコピーをクライアントに提供せずにWCFから返すことはできません。アプリケーション。
using System;
using System.ServiceModel;
[ServiceContract]
interface IService
{
[OperationContract]
TimeSpan GetTimeSpan();
}
class Service : IService
{
public TimeSpan GetTimeSpan() { return DateTime.Now.TimeOfDay; }
}
以前のコードはなぜ機能するのですか?サービス呼び出しの両側に System.dll
があり、OperationContract GetTimeSpan( )
。
これは、 DataContract
を使用した例です。
using System;
using System.ServiceModel;
using System.Runtime.Serialization;
[ServiceContract]
interface IService
{
[OperationContract]
Contract GetContract();
}
[DataContract]
class Contract
{
[DataMember]
public String MyProperty { get; set; }
}
class Service : IService
{
public Contract GetContract() { return new Contract(); }
}
定義したクラスにシリアル化属性を提供しました( Contract
)-これにより、 svcutil.exe
を使用して、クライアントアプリケーションでプロキシクラスを作成できます。シリアル化され、WCFサービスに送信されます。
DataContract
ではない型を返したい場合は、その型を含むアセンブリのコピーをクライアントアプリケーションに提供する必要があります。
発生する必要があることの1つは、ユーザーがプロキシで定義されたクラスではなく、DLLからの型を使用するようにサービス参照を構成する必要があることです- http://msdn.microsoft.com/en-us/library/bb628653.aspx
過去にその道をたどりましたが、実際問題はもちろん、これらは2つの異なるクラスであるため、@ Rich Reuterが提供するリンクをたどる必要があります。
しかし、SOAの第3の教義である「サービスはクラスではなくスキーマとコントラクトを共有する」のように、これが悪い習慣であるという難しい方法を学びました。
もちろん、問題は「規則」に従っていないだけではありません。ある時点で誰かが設定しますが、これを提案する大きな理由がありました-サービスとクライアント間のこのような密結合の価格は、どちらかをリリースするのが非常に難しいことを意味します-サービスを追加する必要がある場合そのクラスの別のフィールド、別のクライアントにサービスを提供する-最初のクライアントが影響を受ける可能性があります。サービスがそのクラス定義で何かを変更する必要がある場合(別のクライアントにサービスを提供するため)-最初のクライアントが再び影響を受け、その逆も同様です-クライアントはサービスのライフサイクルに影響を与える可能性があります。
大規模なプロジェクトでは、これはすぐに大きなメンテナンスの負担になります。