いくつかの値が割り当てられている場合、または列挙型が フラグ 属性。また、列挙型を公開するWebサービスは維持するのが難しいが、実際に実行可能な議論を提供することはできなかったとも述べた。あなたの経験から、WCF Webサービスで列挙型を使用することの長所と短所は何ですか?
人々がウェブサービスで列挙型を避けることを推奨する理由は、それらが微妙な後方互換性の問題を作成するためです。
同じことが通常の列挙型にも当てはまりますが、Webサービスでは、特に.NETで生成されたプロキシ(以下を参照)で問題がさらに明確になります。
パラメータを文字列として定義することにより、APIのユーザーに値が将来変更される可能性があることを知らせます。価値は決して変わらないと思っていても、準備をしておくのは良い習慣です。
このトピックについては、Dare Obasanjoによる good post があります。
私はWCFで列挙型を使用しており、相互運用性のシナリオでも使用しています。サービスの両側を制御すると、作業がしやすくなります。サービスの片側のみを制御する場合は、言及した問題に注意する必要があります。
列挙型は文字列変数よりもはるかに優れているため、他に何を使用するかを選択できます。 enumの代わりに文字列を使用することは、SOAでは「loosey Goosey」と呼ばれるアンチパターンです。
列挙型は、WSDLおよびXSDでxsd:enumeration
スキーマ要素を介して完全にサポートされています。単一の値とフラグスタイルの列挙の両方をサポートします。フラグ列挙の複数の値はスペースで区切られます。
したがって、標準に準拠したプラットフォームで列挙を使用しても問題はありません。
もちろん、それはすべて、このWCFサービスをどこで使用するかによって異なります。
それを使用する単一のアプリケーションの場合、コントラクトを変更しても効果はありません。
複数の内部アプリケーションの場合、コントラクトを変更すると、他のアプリケーションでいくつかの変更が必要になる場合があります。
そして最後に、WCFサービスがパブリックの場合、異なるバージョンのサービスの2つのバージョンを提供して、それらを使用するユーザーがクライアントのバージョンを新しいサービスに転送できるようにする必要があります。
それはすべてあなたのニーズに正直依存しています。
WSDLの列挙型は、メンテナンスの問題と見なす必要があります。
列挙値の追加または削除は、インターフェイスのメジャーアップデートのトリガーです(そうする必要があります!)。列挙型が出力値である場合、現在のクライアントが確立された契約を破らないようにするために、新しいURIを通じてWSDLの新しいバージョンを定義する必要があります(「これらの新しい予期しない値を受け取った場合、 ? ")enumが入力値である場合、これをマイナーアップデートと見なすことができます(「現在のクライアントはこの新しい値について知る必要がないため」)。しかし、これらのクライアントがこの新しいオプション/機能の追加(理由のためにこの新しい列挙値を追加しましたよね?)は、遅かれ早かれ、新しいバージョンのインターフェースに切り替えるように依頼することになります。
そして、これは列挙型の機能的な意味とは関係がないと思います。
ベストプラクティスの側に留まれば、安全です。
Enum以外を使用しても互換性の問題は解決されず、非表示になるだけです。 entを置き換えるためにintを使用するとします。クライアントランタイムが不明な値に達するまで、互換性の問題を本当に解決しましたか、それとも偽装しましたか?
ただし、言及する価値があることは1つあります。WCFプロキシは、明示的に設定された列挙型数値を再作成しません。列挙型が「穴」で宣言されている場合、
enum ErrorCodes
{
OK = 0,
GenericError = 100,
SomeOtherError = 101,
}
クライアント側の表現はこのようになります
enum ErrorCodes
{
OK,
GenericError,
SomeOtherError,
}
...クライアントでは、(int)ErrorCodes.GenericErrorが1になります。
構文の等価性はありますが、数値の等価性はありません。
私はWCFベースのサービスで列挙型を問題なく使用しました。あなたが言及する可能性のある問題は間違いなく考慮すべきことですが、かなり静的な状況で列挙型を適用することを確認すれば、おそらくそれほど問題はありません。
実世界のストーリー(匿名のために値が変更されました)。アプリケーションで暗黙のenum
を使用するために使用します
public enum { orange, banana, mango }
順序と新しい値に関するリファクタリングをいくつか行い、それを明示的にすることにします。
public enum { orange=1, banana=2, grape=3, mango=4 }
不快に見えません...
次に、ウェブサイトが爆発します。スクラッチヘッド、サービスのチェック、デバッグメッセージの追加など、すべて問題ないようです。
ウサギの穴を1日後、理由は、列挙型を戻り値の型として使用していた基本のwcfサービスです。
見たところ、Wcfはdefault値のない列挙型を好みません。
修正:
public enum { wcfBugBane=0, orange=1, banana=2, grape=3, mango=4 }
だから...それはあなたを噛むかもしれません。
ここにアプローチがあります。多分それは面倒です。列挙型を使用できないのは本当に嫌いです。
認識されない値の逆シリアル化を適切に処理し、代わりにデフォルト値を返します。デフォルト値は安全である必要があります-許容可能なフォールバック、またはアプリケーションが例外として認識できるもの。 (「未指定」のように。)
拡張機能により、比較する前にnullチェックを行う必要がなくなります。
[DataContract]
public class EnumValue<T> where T : struct
{
[DataMember]
private string _raw = string.Empty;
[IgnoreDataMember]
private bool _parsed;
[IgnoreDataMember]
private T _parsedValue;
public EnumValue()
{
Set(default(T));
}
public EnumValue(T value)
{
Set(value);
}
internal T Value
{
get
{
if (_parsed) return _parsedValue;
if (!Enum.TryParse<T>(_raw, out _parsedValue))
{
_parsedValue = default(T);
}
_parsed = true;
return _parsedValue;
}
}
public void Set(T value)
{
_raw = value.ToString();
_parsedValue = value;
_parsed = true;
}
}
public static class EnumValueExtensions
{
public static T GetValue<T>(this EnumValue<T> enumValue) where T : struct
{
return enumValue == null ? default(T) : enumValue.Value;
}
public static bool EqualsValue<T>(this EnumValue<T> enumValue, T compareTo) where T : struct
{
return (enumValue.GetValue().Equals(compareTo));
}
}