c# - परिपत्र निर्भरता को सी#में नाम स्थान के साथ क्यों अनुमति है?




namespaces circular-dependency (2)

सी # में आपको फ़ाइल सी सी में एक बयान देने की अनुमति है (जिसमे MyApp.A का नाम स्थान है):

using MyApp.B;

जबकि फ़ाइल b.cs (जिसमें MyApp.B का नेमस्पेस है) पहले से ही कथन है

using MyApp.A;

अगर एक समान निर्भरता अलग-अलग डीएलएल (जहां a.dll का संदर्भ b.dll और इसके विपरीत है) में मौजूद होगा, तो इसे परिपत्र निर्भरता त्रुटि के कारण अनुमति नहीं दी जाएगी, इसलिए नामस्थान (और संकलक के साथ इसकी अनुमति क्यों नहीं है यहां तक ​​कि एक चेतावनी का उत्पादन)? क्या यह ऐसा करने के लिए एक कोड गंध नहीं है?


आपकी धारणा है कि विधानसभाएं एक-दूसरे के संदर्भ को पार नहीं कर सकती हैं, वे गलत हैं। यह स्थापित करने के लिए एक दर्द है, और दृश्य स्टूडियो, आईआईआरसी के माध्यम से करना आसान नहीं है, लेकिन यह संभव है।

सबसे पहले, हम 3 टेक्स्ट फाइल बनाते हैं:

A.cs :

using B;

namespace A
{
  public class AA
  {
    public AA(BB val)
    {
    }
  }
}

B.cs :

using A;

namespace B
{
  public class BB
  {
    public BB(AA val)
    {
    }
  }
}

और, A_prime.cs :

namespace A
{
  public class AA
  {
    public AA()
    {
    }
  }
}

ध्यान दें कि ये कक्षाएं उपयोगी या उपयोग करने योग्य नहीं होती हैं बस बिंदु को प्रदर्शित करने के लिए - यह है कि हमारे पास A लिए दो संभव स्रोत हैं - जिसमें से हम बाहर निकलते हैं या B पर निर्भरता की हमारी ज़रूरत के चारों ओर "काम करते हैं" और अन्य जहां हम नहीं करते।

हम तब संकलन करते हैं:

csc /out:A.dll /target:library A_prime.cs
csc /out:B.dll /target:library /reference:A.dll B.cs
csc /out:A.dll /target:library /reference:B.dll A.cs

अंतिम परिणाम - हमारे पास दो विधानसभाएं हैं जो प्रत्येक दूसरे को क्रॉस-रेफरेंस 1

इसी तरह, .net ढांचे में ही, हमारे पास बहुत सारे क्रॉस-रेफ्रेंसिंग हो रहा है - System.Xml.dll System.dll , System.Xml.dll और System.Configuration.dll सभी परस्पर क्रॉस-रेफ्रेंसिंग हैं। यद्यपि उनके पास शायद ऊपर की तुलना में अधिक परिष्कृत बिल्ड सेटअप है - अलग स्रोत फाइलों की बजाय बूटस्ट्रैपिंग करने के लिए एकल स्रोत फ़ाइल और प्रतीकों का उपयोग करना।

और अंत में, नामस्थानों को संबोधित करने के लिए - नामस्थान कार्यक्षमता का एक तर्कसंगत समूह है कई विधानसभाएं एक एकल नेमस्पेस में प्रकारों को योगदान दे सकती हैं। एक एकल विधानसभा कई नामस्थानों में प्रकारों को योगदान दे सकती है। कोई तार्किक कारण नहीं है कि कई नामस्थानों के अंदर दोनों दिशाओं में दोनों दिशाओं के संदर्भ में किस प्रकार के संदर्भ में सक्षम नहीं होना चाहिए।

1 यह काम csc का संस्करण प्रदान करता है, यदि आप 0.0.0.0 की संस्करण संख्या निर्दिष्ट करने के लिए चूक का उपयोग कर रहे हैं, यदि स्रोत में कोई AssemblyVersion संस्करण नहीं है। यदि यह csc एक विशेष उदाहरण के लिए मामला नहीं है (मुझे याद है कि यह कुछ पुराने लोगों पर अलग था), तो आपको यह विशेषता सुनिश्चित करने की आवश्यकता हो सकती है कि A.dll के दो संयोजन एक ही पहचान के साथ असेंबली का उत्पादन करें।

इसी तरह, मजबूत नामकरण जैसे विवरण प्रक्रिया को अधिक श्रमसाध्य बना सकते हैं।

2 "लिटिल-आर" संदर्भ, नहीं "बिग-आर" संदर्भ। जैसे विभिन्न प्रकार के एक दूसरे का इस्तेमाल करते हुए "सी # में एक संदर्भ क्या है?" शर्तों।


डेमियन_ द_अन्वेलीवीयर ने लिखा है कि नामस्थान कार्यक्षमता का एक तर्कसंगत समूह है

हंस पैटाट ने नामस्थान लिखा है लेकिन कंपाइलर के लिए एक सरल संकेत नहीं है

मैं विस्तृत करना चाहता हूं कि यह वास्तव में आपके कोड बेस में एक घटक होने पर निर्भर करता है। एक घटक प्रकार का एक समूह है एक घटक एक या कई नामस्थानों को एक या कई विधानसभाओं में परिभाषित कर सकता है। महत्वपूर्ण बात ये है कि घटकों के बीच कोई निर्भरता चक्र नहीं है। क्योंकि एक घटक विकास की एक इकाई है , और अगर घटक ए और बी परस्पर एक दूसरे का उपयोग कर रहे हैं, तो वे विकास की एक बड़ी इकाई का गठन करते हैं, वे स्वतंत्र रूप से विकसित नहीं हो सकते हैं, वे एक सुपर-घटक या दूसरे शब्दों में, यह जड़ है स्पेगेटी कोड का

अपने प्रश्न का उत्तर देने के लिए, परिपत्र निर्भरता को सी # में नाम स्थान के साथ क्यों अनुमति है? आपके प्रश्न के पीछे निहित विवरण यह है कि नामस्थानों को तार्किक घटकों को परिभाषित करने के लिए उपयोग किया जाता है। लेकिन नेमस्पेस का उपयोग प्रकार नाम टक्कर से बचने के लिए भी किया जा सकता है, ताकि किसी सार्वजनिक एपीआई की कक्षाओं को एक संरचित तरीके से प्रस्तुत किया जा सके, ताकि विस्तार विधियों का एक सेट हो सके ... इसलिए मुझे लगता है कि सी # डिजाइनर निश्चित तौर पर नहीं चाहता था तार्किक घटकीकरण के लिए केवल नामस्थान की अवधारणा को सीमित करें

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

क्या यह ऐसा करने के लिए एक कोड गंध नहीं है?

मेरी राय में यह है, क्योंकि यदि एक बड़ी असेंबली में निर्भरता चक्र के साथ कई नामस्थान शामिल हैं, तो किसी को कोड से समग्र संरचना को समझने का कोई तरीका नहीं है। मैं एनडीएप नामक एक नेट नेटिक विश्लेषक पर काम करता हूं जो नामस्थानों के निर्भरता चक्र की जांच कर सकता है और निर्भरता ग्राफ़ और निर्भरता मैट्रिक्स के माध्यम से वर्तमान परिणाम देख सकता है। हमारे पास 400 से अधिक नाम स्थान हैं और हम उन्हें एक दर्जन से अधिक असेंबलियों में ठीक से सभी स्तरित रखने में खुशी रखते हैं। निर्भरता मैट्रिक्स एक नज़र में स्तरित नामस्थान संरचना को कल्पना करने का एक आसान तरीका प्रदान करता है।





circular-reference