.NET मॉड्यूल नेमस्पेस से अलग मॉड्यूल फ़ाइल नाम क्यों करते हैं?


9

योजना प्रोग्रामिंग भाषा (R6RS मानक) के कार्यान्वयन में मैं एक मॉड्यूल को निम्नानुसार आयात कर सकता हूं:

(import (abc def xyz))

सिस्टम एक फ़ाइल की तलाश करने की कोशिश करेगा $DIR/abc/def/xyz.slsजहां $DIRकुछ निर्देशिका है जहां आप अपना स्कीम मॉड्यूल रखते हैं। xyz.slsमॉड्यूल के लिए स्रोत कोड है और यदि आवश्यक हो तो इसे मक्खी पर संकलित किया जाता है।

रूबी, पायथन, और पर्ल मॉड्यूल सिस्टम इस संबंध में समान हैं।

दूसरी ओर C # थोड़ा अधिक शामिल है।

सबसे पहले, आपके पास dll फाइलें हैं जिन्हें आपको प्रति प्रोजेक्ट के आधार पर संदर्भित करना चाहिए। आपको प्रत्येक को स्पष्ट रूप से संदर्भित करना चाहिए। यह एक निर्देशिका में dll फ़ाइलों को छोड़ने और नाम से उन्हें लेने से अधिक कहने में शामिल है।

दूसरा, dll फ़ाइल नाम और dll द्वारा प्रस्तावित नामस्थान के बीच एक-से-एक नामकरण पत्राचार नहीं है। मैं इस लचीलेपन की सराहना कर सकता हूं, लेकिन यह हाथ से भी निकल सकता है (और है)।

इस ठोस को बनाने के लिए, यह अच्छा होगा यदि, जब मैं यह कहता हूं using abc.def.xyz;, तो C # किसी फ़ाइल को खोजने की कोशिश करेगा abc/def/xyz.dll, कुछ निर्देशिका में जो C # में देखना जानता है (प्रति प्रोजेक्ट के आधार पर विन्यास योग्य)।

मैं रूबी, पायथन, पर्ल, स्कीम से निपटने के तरीके को अधिक सुरुचिपूर्ण ढंग से ढूंढता हूं। ऐसा लगता है कि उभरती हुई भाषाएँ सरल डिजाइन के साथ जाती हैं।

.NET / C # दुनिया इस तरह से चीजें क्यों करती है, अतिरिक्त स्तर के अप्रत्यक्ष स्तर के साथ?


10
.NET की असेंबली और क्लास रिज़ॉल्यूशन मैकेनिज़्म ने 10 साल से अधिक समय तक काम किया है। मुझे लगता है कि आपके पास एक मूलभूत गलतफहमी (या पर्याप्त शोध नहीं) की कमी है, इस बारे में कि इसे इस तरह से क्यों बनाया गया है - उदाहरण के लिए बाइंड समय पर असेंबली पुनर्निर्देशन आदि का समर्थन करना और कई अन्य उपयोगी रिज़ॉल्यूशन तंत्र
केव

मुझे पूरा यकीन है कि एक प्रयोग कथन से DLL रिज़ॉल्यूशन साइड-बाय-साइड निष्पादन को तोड़ देगा। इसके अलावा अगर कोई 1 से 1 था तो आपको mscorlib के सभी नामस्थानों के लिए 50 dll की आवश्यकता होगी, या उन्हें नामस्थानों के विचार को छोड़ना होगा
कॉनराड फ्रैक्स

परोक्ष का एक अतिरिक्त स्तर? हम्म्म्म
user541686

@gilles संपादन के लिए धन्यवाद और प्रश्न को बेहतर बनाने के लिए!
धर्मटेक

आपके कुछ बिंदु विज़ुअल स्टूडियो के लिए अजीब हैं, और उनकी तुलना किसी भाषा से करना बिलकुल उचित नहीं है ( उदाहरण के लिए , प्रोजेक्ट्स में DLL संदर्भ)। पूर्ण .NET वातावरण के लिए एक बेहतर तुलना जावा + ग्रहण होगी।
रॉस पैटरसन

जवाबों:


22

फ्रेमवर्क डिज़ाइन दिशानिर्देश धारा 3.3 में निम्नलिखित एनोटेशन । असेंबली और डीएलएस के नाम इस बात की अंतर्दृष्टि प्रदान करते हैं कि नामस्थान और असेंबली अलग-अलग क्यों हैं।

BRAD ABRAMS CLR के डिजाइन में अर्ली हमने प्लेटफ़ॉर्म (असेंबली) की पैकेजिंग और परिनियोजन दृश्य से प्लेटफ़ॉर्म (नेमस्पेस) के डेवलपर दृश्य को अलग करने का निर्णय लिया। यह पृथक्करण प्रत्येक को अपने स्वयं के मानदंडों के आधार पर स्वतंत्र रूप से अनुकूलित करने की अनुमति देता है। उदाहरण के लिए, हम समूह प्रकारों के लिए फैक्टर नेमस्पेस से मुक्त हैं जो कार्यात्मक रूप से संबंधित हैं (उदाहरण के लिए, System.IO में सभी I / O सामान) जबकि असेंबली को प्रदर्शन (लोड समय), परिनियोजन, सर्विसिंग या संस्करणगत कारणों के लिए फैक्टर किया जा सकता है ।


अब तक के सबसे आधिकारिक स्रोत की तरह लगता है। धन्यवाद कोनराड!
धर्मटेक

शापित-आधिकारिक जवाब पाने के लिए +1। लेकिन यह भी, हर " क्यों करता है C # करते हैं <एक्स> " सवाल भी " जावा करता है <एक्स> के लेंस के माध्यम से इस प्रकार देखा जाना चाहिए: ... ", क्योंकि सी # (स्पष्ट रूप से या नहीं) सूर्य की प्रतिक्रिया थी और विंडोज पर जावा के लिए माइक्रोसॉफ्ट के अलग-अलग एजेंडा।
रॉस पैटरसन

6

यह लचीलापन जोड़ता है और मांग पर पुस्तकालयों (जिसे आप अपने प्रश्न में मॉड्यूल कहते हैं) को लोड करने की अनुमति देता है।

एक नामस्थान, कई पुस्तकालय:

एक लाभ यह है कि मैं आसानी से एक पुस्तकालय को दूसरे से बदल सकता हूं। मान लीजिए कि मेरे पास एक नाम स्थान MyCompany.MyApplication.DALऔर एक पुस्तकालय है DAL.MicrosoftSQL.dll, जिसमें सभी SQL क्वेरी और अन्य सामान हैं जो डेटाबेस के लिए विशिष्ट हो सकते हैं। अगर मैं चाहता हूं कि एप्लिकेशन ओरेकल के साथ संगत हो, तो मैं बस DAL.Oracle.dllएक ही नाम स्थान रखता हूं । अब से, मैं उन ग्राहकों के लिए एक लाइब्रेरी के साथ एप्लिकेशन वितरित कर सकता हूं जिन्हें Microsoft SQL सर्वर के साथ संगतता की आवश्यकता है, और Oracle का उपयोग करने वाले ग्राहकों के लिए अन्य लाइब्रेरी के साथ।

इस स्तर पर नामस्थान बदलने से usingप्रत्येक डेटाबेस के लिए स्रोत कोड के अंदर सभी s जाने के लिए या तो डुप्लिकेट कोड या आवश्यकता होगी ।

एक पुस्तकालय, कई नामस्थान:

एक पुस्तकालय में कई नाम स्थान होने के कारण पठनीयता के लिहाज से भी फायदेमंद है। यदि, किसी कक्षा में, मैं केवल एक नामस्थान का उपयोग करता हूं, तो मैं फ़ाइल के शीर्ष पर सिर्फ एक ही लगाता हूं।

  • एक बड़े पुस्तकालय के सभी नामस्थान होने के बजाय स्रोत कोड को पढ़ने वाले व्यक्ति के लिए और स्वयं लेखक के लिए दोनों को भ्रमित करना होगा, जिसमें इंटेलीजेंस के पास दिए गए संदर्भ में सुझाव देने के लिए बहुत सी चीजें होंगी।

  • छोटी लाइब्रेरी होने से, प्रत्येक फ़ाइल में एक लाइब्रेरी का प्रदर्शन प्रभाव पड़ेगा: प्रत्येक लाइब्रेरी को मेमोरी में मांग पर लोड किया जाना चाहिए और एप्लिकेशन को चलाते समय वर्चुअल मशीन द्वारा संसाधित किया जाना चाहिए; लोड करने के लिए कम फ़ाइलों का मतलब थोड़ा बेहतर प्रदर्शन है।


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

2

ऐसा लगता है कि आप "नेमस्पेस" और "मॉड्यूल" दोनों की शब्दावली को ओवरलोड करना चुन रहे हैं। यह कोई आश्चर्य नहीं होना चाहिए कि आप चीजों को "अप्रत्यक्ष" के रूप में देखते हैं जब वे आपकी परिभाषाओं में फिट नहीं होते हैं।

सी # सहित नामस्थानों का समर्थन करने वाली अधिकांश भाषाओं में, एक नाम स्थान एक मॉड्यूल नहीं है। एक नेमस्पेस, स्कॉपिंग नामों का एक तरीका है। मॉड्यूल स्कूपिंग व्यवहार का एक तरीका है।

सामान्य तौर पर, जबकि .Net रनटाइम एक मॉड्यूल के विचार का समर्थन करता है (एक अलग परिभाषा जो आप उपयोग कर रहे हैं की तुलना में थोड़ी भिन्नता के साथ), यह शायद ही कभी इस्तेमाल किया जाता है; मैंने केवल इसे SharpDevelop में निर्मित परियोजनाओं में उपयोग किया है, ज्यादातर देखा है ताकि आप विभिन्न भाषाओं में निर्मित मॉड्यूल से एक ही DLL का निर्माण कर सकें। इसके बजाय, हम एक गतिशील रूप से जुड़े पुस्तकालय का उपयोग करके पुस्तकालयों का निर्माण करते हैं।

सी # में, नामस्थान किसी भी "अप्रत्यक्ष की परत" के बिना हल करते हैं जब तक कि वे सभी एक ही बाइनरी में न हों; किसी भी अप्रत्यक्ष की आवश्यकता कंपाइलर और लिंकर की एक जिम्मेदारी है जिसे आपको ज्यादा विचार करने की आवश्यकता नहीं है। एक बार जब आप कई निर्भरता के साथ एक परियोजना का निर्माण शुरू करते हैं, तो आप बाहरी पुस्तकालयों का संदर्भ देते हैं। एक बार जब आपके प्रोजेक्ट ने बाहरी लाइब्रेरी (DLL) का संदर्भ लिया है, तो कंपाइलर आपके लिए इसे ढूंढता है।

स्कीम में, यदि आपको किसी बाहरी पुस्तकालय को लोड करने की आवश्यकता है, तो आपको (#%require (lib "mylib.ss"))पहले जैसा कुछ करना होगा , या जैसा कि मुझे याद है, सीधे विदेशी फ़ंक्शन इंटरफ़ेस का उपयोग करें। यदि आप बाहरी बायनेरिज़ का उपयोग कर रहे हैं, तो आपके पास बाहरी बायनेरिज़ को हल करने के लिए समान मात्रा में काम है। संभावना है कि आपने ज्यादातर पुस्तकालयों का उपयोग किया है इसलिए आमतौर पर इसका इस्तेमाल किया जाता है कि एक स्कीम-आधारित शिम है जो आपके पास से सार करता है, लेकिन यदि आपको कभी भी 3 पार्टी लाइब्रेरी के साथ अपना एकीकरण लिखना है, तो आपको अनिवार्य रूप से "लोड" करने के लिए कुछ काम करना होगा। " पुस्तकालय।

रूबी में, मॉड्यूल, नाम स्थान और फ़ाइल नाम वास्तव में बहुत कम जुड़े हुए हैं जितना आप मान लेते हैं; LOAD_PATH चीजों को थोड़ा जटिल बनाता है, और मॉड्यूल घोषणाएं कहीं भी हो सकती हैं। पायथन शायद उन चीजों को करने के करीब है जिस तरह से आपको लगता है कि आप स्कीम में देख रहे हैं, सिवाय इसके कि सी में 3 पार्टी लाइब्रेरी अभी भी एक (छोटी) शिकन जोड़ते हैं।

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

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

एक बात यह है कि C # इकोसिस्टम के पास अभी भी इन अपर बाइनरी निर्भरताओं के प्रबंधन के लिए अपेक्षाकृत अपरिपक्व समर्थन है; जावा के पास कई वर्षों से मावेन है ताकि यह सुनिश्चित किया जा सके कि आपके पास अपनी सभी आवश्यक निर्भरताएं हैं, जबकि सी # में अभी भी काफी प्राइमिटिव मेक-अप दृष्टिकोण है जिसमें रणनीतिक रूप से फाइलों को समय से पहले सही स्थान पर रखना शामिल है।


1
निर्भरता के प्रबंधन के बारे में आप नुगेट पर एक नज़र रखना चाहते हैं । यहाँ फिल Haack से इसके बारे में एक अच्छा लेख है
कॉनरेड Frix

R6RS स्कीम के कार्यान्वयन में मैंने (इकारस, चेज़ और एप्सिलॉन, उदाहरण के लिए) का उपयोग किया है, निर्भरताएँ पुस्तकालय आयात के आधार पर स्वचालित रूप से नियंत्रित की जाती हैं। निर्भरता पाई जाती है और यदि आवश्यक हो तो भविष्य के आयात के लिए संकलित और कैश की जाती है।
धर्मटेक

नुगेट के साथ परिचित, और इस तरह मेरी टिप्पणी है कि यह "अपेक्षाकृत अपरिपक्व" है
जेसन ट्रू
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.