2008-11-28 13 views
38

मैंने कुछ लोगों को यह कहते हुए सुना है कि enums बुरा हैं और वेब सेवाओं में उपयोग नहीं किया जाना चाहिए क्योंकि सर्वर और क्लाइंट के बीच होने वाले विसंगतियों के कारण कुछ मूल्य आवंटित किए जाते हैं, या यदि enum को Flags के साथ चिह्नित किया गया है विशेषता। उन्होंने यह भी कहा कि वेब सेवाओं को उजागर करने वाली वेब सेवाओं को बनाए रखना मुश्किल है लेकिन वास्तव में मुझे व्यवहार्य तर्क नहीं दे सका। तो आपके अनुभव से डब्लूसीएफ वेब सेवा में enums का उपयोग करने के पेशेवर और विपक्ष क्या हैं?क्या आप अपनी डब्ल्यूसीएफ वेब सेवाओं में एनम प्रकार का उपयोग करते हैं?

उत्तर

38

लोगों को वेबसाइसेस में enums से बचने की सलाह है क्योंकि वे सूक्ष्म पिछड़ा संगत समस्याओं का निर्माण करते हैं।

यह नियमित enums पर लागू होता है लेकिन वेब सेवाओं में समस्या विशेष रूप से .NET से उत्पन्न प्रॉक्सी में नीचे स्पष्ट है (नीचे देखें)।

  • यदि गणना केवल इनपुट है तो आपके पास कोई समस्या नहीं है। ग्राहक एक उपयोग कर रहा है
    • :
    • यदि आप एक नए तत्व जोड़ सकते हैं और आप इसे वापस की गणना तो एक बाहर पैरामीटर हो सकता है, तो पुराने ग्राहकों की समस्याओं हो सकता था।एनईटी से उत्पन्न प्रॉक्सी इससे पहले कॉलर इसे संभालने से पहले टूट जाएगा (deserialization में)
    • भले ही प्रॉक्सी के जेनरेट कोड ने परिवर्तन का समर्थन किया हो (उदाहरण के लिए यदि यह स्ट्रिंग के लिए गणना करता है) क्लाइंट में उपयोगकर्ता कोड ठीक से नई अप्रत्याशित मूल्य पर कार्रवाई नहीं कर सकते हैं (यह आसानी से एक कभी नहीं निष्पादित पथ हो सकता है)

एक स्ट्रिंग आप अपने एपीआई के उपयोगकर्ता है कि मूल्य भविष्य में बदल सकता संकेत के रूप में पैरामीटर को परिभाषित करके। भले ही आपको लगता है कि मूल्य कभी नहीं बदलेगा, तैयार होने का एक अच्छा अभ्यास है।

इस विषय पर डियर ओबासंजो द्वारा good post है।

+0

enums की पिछड़े संगतता के लिए एक समाधान के रूप में, उन्हें [डेटाकंट्रैक्ट] के रूप में घोषित किया जा सकता है और केवल पुराने मान [डेटामेम्बर] के रूप में सेट किए गए हैं, लेकिन विशेषता के बिना नए मान छोड़े गए हैं। –

1

मैंने बिना किसी समस्या के मेरी डब्ल्यूसीएफ आधारित सेवाओं में enums का उपयोग किया है। आपके द्वारा उल्लेख किए जाने वाले संभावित मुद्दे निश्चित रूप से विचार करने वाली चीजें हैं, हालांकि यदि आप सुनिश्चित करते हैं कि आप काफी स्थिर परिस्थितियों में enums लागू करते हैं तो आपको शायद अधिक परेशानी नहीं होगी।

3

बेशक, यह सब इस डब्ल्यूसीएफ सेवा का उपयोग करने के लिए कहां जा रहा है इस पर निर्भर करता है।

यदि यह एक ऐसा एप्लिकेशन है जो इसका उपयोग करेगा, तो अनुबंध को बदलने से कोई प्रभाव नहीं पड़ेगा।

यदि यह कई आंतरिक अनुप्रयोग हैं, तो अनुबंध को बदलने के लिए अन्य अनुप्रयोगों में कुछ बदलावों की आवश्यकता हो सकती है।

और अंत में, यदि डब्ल्यूसीएफ सेवा सार्वजनिक है, तो आपको अलग-अलग संस्करणों के साथ सेवा के 2 संस्करण प्रदान करना पड़ सकता है ताकि लोगों को उपभोग करने वाले लोगों के पास क्लाइंट के अपने संस्करण को नई सेवा में स्थानांतरित करने का समय हो।

यह सब आपकी आवश्यकताओं पर ईमानदारी से निर्भर करता है।

15

मैंने डब्ल्यूसीएफ में इंटरऑपरेबिलिटी परिदृश्यों में भी enums का उपयोग किया है। यदि आप सेवा के दोनों तरफ नियंत्रित करते हैं, तो यह काम करना आसान है। यदि आप केवल सेवा के एक तरफ नियंत्रण करते हैं, तो आपको उन मुद्दों के बारे में जानने की आवश्यकता है जिन्हें आपने बताया था।

Enums इतना बेहतर है कि स्ट्रिंग चर, या आप और क्या उपयोग करने के लिए चुन सकते हैं। enums के बजाय स्ट्रिंग का उपयोग एसओए में "ढीला गूसी" नामक एक विरोधी पैटर्न है।

10

xsd:enumeration स्कीमा तत्व के माध्यम से डब्ल्यूएसडीएल और एक्सएसडी में गणना पूरी तरह से समर्थित हैं। यह एकल मूल्यों और झंडे-शैली दोनों समीकरणों के लिए समर्थन प्रदान करता है, जहां झंडे की गणना में कई मान रिक्त स्थान से अलग होते हैं।

तो आपको किसी मानक मानकों के अनुरूप गणनाओं का उपयोग करके कोई समस्या नहीं होनी चाहिए।

+1

एमएमआईंड द्वारा उल्लिखित पिछड़ा संगतता एक सीरियोज चिंता है, जिसे अक्सर अनदेखा किया जाता है। –

2

डब्ल्यूएसडीएल में एनम्स को रखरखाव के लिए चिंता के रूप में माना जाना चाहिए।

एक गणना मूल्य जोड़ना या निकालना इंटरफ़ेस के एक बड़े अद्यतन के लिए एक ट्रिगर (होना चाहिए!) है। यदि enum एक आउटपुट मान है, तो आपको एक नए यूआरआई के माध्यम से डब्लूएसडीएल के एक नए संस्करण को परिभाषित करने की आवश्यकता है, ताकि मौजूदा ग्राहकों को स्थापित अनुबंध को तोड़ने से रोक सके ("अगर वे इन नए, अप्रत्याशित मूल्यों पर प्राप्त होते हैं तो क्या होगा वापसी? ") यदि enum एक इनपुट मान है, तो आप इसे एक मामूली अपडेट के रूप में मान सकते हैं (" चूंकि मौजूदा ग्राहकों को इस नए मूल्य के बारे में जानने की आवश्यकता नहीं होगी "), लेकिन फिर, उन ग्राहकों के लिए लाभ का एकमात्र तरीका इस नए विकल्प/कार्यक्षमता के अतिरिक्त से (आपने इस नए एनम वैल्यू को किसी कारण से जोड़ा है, है ना?) इंटरफ़ेस के नए संस्करण में, बाद में या जल्द ही स्विच करने के लिए कहेंगे।

और मुझे लगता है कि यह enum के कार्यात्मक अर्थ के साथ नहीं है, मुझे लगता है।

सर्वोत्तम प्रथाओं के पक्ष में रहें, और आप सुरक्षित रहेंगे।

+0

एनम्स को [डेटाकंट्रैक्ट] के रूप में घोषित किया जा सकता है और केवल पुराने मान [डेटामेम्बर] के रूप में सेट किए गए हैं, लेकिन नए प्रमुख रिलीज –

2

किसी और चीज का उपयोग करना लेकिन enums आपके संगतता मुद्दे को हल नहीं करता है, यह केवल इसे छुपाता है। मान लीजिए कि आप एक enum को प्रतिस्थापित करने के लिए int का उपयोग करते हैं। क्या आपने वास्तव में संगतता समस्या हल की है या क्लाइंट रनटाइम अज्ञात मान को हिट करने तक इसे छिपा लिया है?

हालांकि, एक बात उल्लेखनीय है: डब्ल्यूसीएफ प्रॉक्सी स्पष्ट रूप से एनम न्यूमेरिक मान सेट नहीं करते हैं। enum तरह

enum ErrorCodes 
{ 
    OK = 0, 
    GenericError = 100, 
    SomeOtherError = 101, 
} 

, "छेद" के साथ घोषित किया जाता है, तो ग्राहक के पक्ष प्रतिनिधित्व इस

enum ErrorCodes 
{ 
    OK, 
    GenericError, 
    SomeOtherError, 
} 

तरह होगा ... जो (int) ErrorCodes.GenericError 1 होने में ग्राहक परिणामों पर

आपके पास वाक्य रचनात्मक समकक्ष होगा, लेकिन संख्यात्मक समकक्ष नहीं होगा।

+0

तक विशेषता के बिना नए मान छोड़े गए हैं। नेट के हाल के संस्करणों में "छेद" को संरक्षित नहीं किया गया है (उदाहरण के लिए 4.5.1)। – user3085342

0

यहां एक दृष्टिकोण है। शायद यह बोझिल है। मैं वास्तव में enums का उपयोग करने में सक्षम नहीं है नापसंद।

यह एक अपरिचित मूल्य के deserialization संभालता है, इसके बजाय डिफ़ॉल्ट मान लौटता है। डिफ़ॉल्ट मान को सुरक्षित होने की आवश्यकता होगी - या तो एक स्वीकार्य फॉलबैक या कुछ ऐसा जो एप्लिकेशन असाधारण के रूप में पहचाना जा सके। ("अनिर्दिष्ट" की तरह।)

एक्सटेंशन तुलना करने से पहले शून्य-जांच करने से रोकते हैं।

[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)); 
    } 
} 
संबंधित मुद्दे