Microsoft ने ऐसी असेंबली कैसे बनाईं जिनके परिपत्र संदर्भ हैं?


107

.NET BCL में बीच में सर्कुलर रेफरेंस हैं:

  • System.dll तथा System.Xml.dll
  • System.dll तथा System.Configuration.dll
  • System.Xml.dll तथा System.Configuration.dll

यहां .NET रिफलेक्टर से एक स्क्रीनशॉट दिखाया गया है, जो दिखाता है कि मेरा क्या मतलब है:

यहां छवि विवरण दर्ज करें

Microsoft ने इन विधानसभाओं को कैसे बनाया यह मेरे लिए एक रहस्य है। क्या इसकी अनुमति देने के लिए एक विशेष संकलन प्रक्रिया की आवश्यकता है? मुझे लगता है कि यहां कुछ दिलचस्प चल रहा है।


2
बहुत अच्छा सवाल है। मैंने वास्तव में इस का निरीक्षण करने के लिए समय नहीं लिया है, लेकिन मुझे उत्तर जानने के लिए उत्सुक हूं। वास्तव में, ऐसा लगता है कि डायकम ने एक समझदारी प्रदान की है।
नोल्डोरिन

3
उन सभी को एक में विलय नहीं किया जाता है, यदि वे सभी एक दूसरे की आवश्यकता होती है? क्या इसका कोई व्यावहारिक कारण है?
एंड्रियास पीटरसन

1
दिलचस्प सवाल ... मैं एरिक लिपर्ट का जवाब जानना चाहूंगा! और जैसा कि एंड्रियास ने कहा, मुझे आश्चर्य है कि उन्होंने सब कुछ एक ही विधानसभा में क्यों नहीं रखा ...
थॉमस लेवेस्क

यदि एक विधानसभा को अद्यतन करने की आवश्यकता है, तो उन्हें दूसरे को छूने की आवश्यकता नहीं होगी। यही कारण है कि मैं देख रहा हूँ। दिलचस्प सवाल हालांकि
Atmocreations

2
: इस प्रस्तुति पर एक नज़र (asmmeta फ़ाइलें) ले लो msakademik.net/academicdays2005/Serge_Lidin.ppt
Mehrdad Afshari

जवाबों:


58

मैं केवल यह बता सकता हूं कि मोनो परियोजना यह कैसे करती है। प्रमेय काफी सरल है, हालांकि यह एक कोड गड़बड़ देता है।

वे पहले System.Configuration.dll को संकलित करते हैं, भाग के बिना System.Xml.dll के संदर्भ की आवश्यकता होती है। इसके बाद, वे System.Xml.dll को सामान्य तरीके से संकलित करते हैं। अब जादू आता है। वे System.configuration.dll को recompile करते हैं, जिस भाग को System.Xml.dll के संदर्भ की आवश्यकता होती है। अब परिपत्र संदर्भ के साथ एक सफल संकलन है।

संक्षेप में:

  • A को B की आवश्यकता वाले कोड और B के संदर्भ के बिना संकलित किया गया है।
  • बी संकलित है।
  • A को फिर से जोड़ दिया गया है।

1
इसे Visual Studio द्वारा ब्लॉक किया गया है, लेकिन कमांड लाइन कंपाइलर (csc.exe) का उपयोग करके सीधे किया जा सकता है। मेरा जवाब देखिए।
अल्फ्रेड मायर्स

14
मुझे पता है। मोनो का मुख्य बिल्ड सिस्टम विजुअल स्टूडियो नहीं है। लगता है कि माइक्रोसोफ्ट या तो नहीं है।
डाइकैम

35

RBarryYoung और Dykam कुछ पर हैं। Microsoft आंतरिक उपकरण का उपयोग करता है जो असेंबली को अलग करने के लिए ILDASM का उपयोग करता है, सभी आंतरिक / निजी सामान और विधि निकायों को छीन लेता है और IL को फिर से दबाता है (ILASM का उपयोग करके) जिसे 'निर्जलित विधानसभा' या मेटाडेटा असेंबली कहा जाता है। यह हर बार किया जाता है जब विधानसभा के सार्वजनिक इंटरफ़ेस को बदल दिया जाता है।

निर्माण के दौरान, वास्तविक के बजाय मेटाडेटा असेंबलियों का उपयोग किया जाता है। इस तरह चक्र टूट गया है।


1
दिलचस्प जवाब, क्या आपके पास कोई लिंक है?
हेंक होल्टरमैन

मैं उपकरण के लिए बाहरी संदर्भ खोजने की कोशिश कर रहा हूं। मुझे नहीं लगता कि यह Microsoft के बाहर प्रकाशित किया गया है, लेकिन अवधारणा सरल है: डिसएम्बे-स्ट्रिप इंटर्नल्स-रीअसेंबल।
श्रीजान जोविक

सहमत - दिलचस्प जवाब। इसे वापस करने के लिए कुछ लिंक अच्छे होंगे।
ड्रू नोक

हां, यह वास्तव में ऐसा ही है (व्यक्तिगत अनुभव से)।
पावेल मिनेव

1
निर्माण होने के बाद तक उन्हें दृढ़ता से हस्ताक्षरित नहीं किया जाता है (वे हस्ताक्षर किए जाने में देरी करते हैं), इसलिए निर्जलित विधानसभाओं पर हस्ताक्षर नहीं किए जाते हैं।
बजे श्रीजान जोविक

26

यह उस तरह से किया जा सकता है जैसा कि डायकम ने वर्णित किया है, लेकिन विजुअल स्टूडियो आपको इसे करने से रोकता है।

आपको सीधे कमांड-लाइन कंपाइलर csc.exe का उपयोग करना होगा।

  1. csc / target: पुस्तकालय ClassA.cs

  2. csc / target: Library ClassB.cs /reference:ClassA.dll

  3. csc / target: Library ClassA.cs ClassC.cs /reference:ClassB.dll


//ClassA.cs
namespace CircularA {
    public class ClassA {
    }
}


//ClassB.cs
using CircularA;
namespace CircularB {
    public class ClassB : ClassA  {
    }
}


//ClassC.cs
namespace CircularA {
    class ClassC : ClassB {
    }
}

आप इसे विज़ुअल स्टूडियो में भी कर सकते हैं, हालांकि यह काफी कठोर भी है, मूल तरीका # इफ़ेक्ट का उपयोग करना है और सॉल्यूशन एक्सप्लोरर का उपयोग करके संदर्भ को हटा देना है, जो कि तीसरे चरण में है। दूसरी तरह से मैं सोच रहा हूं कि एक ही प्रोजेक्ट फाइल है जिसमें एक ही फाइल है लेकिन अलग-अलग संदर्भ। यह काम करेगा क्योंकि आप बिल्ड ऑर्डर को निर्दिष्ट कर सकते हैं।
डायकम

जहाँ तक मुझे पता है, यहाँ इसका परीक्षण नहीं कर सकते।
डायकम

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

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

यह थोड़ा सा श्रीजन के उत्तर की तरह है, हालांकि एक अलग तरीका है।
डायकम

18

जब तक आप प्रोजेक्ट संदर्भ का उपयोग नहीं करते, तब तक Visual Studio में इसे करना बहुत आसान है ... इसे आज़माएँ:

  1. दृश्य स्टूडियो खोलें
  2. 2 क्लास लाइब्रेरी प्रोजेक्ट्स "ClassLibrary1" और "ClassLibrary2" बनाएं।
  3. बिल्ड
  4. ClassLibrary1 से चरण 3 में बनाए गए dll पर ब्राउज़ करके ClassLibrary2 का संदर्भ जोड़ें।
  5. ClassLibrary2 से चरण 3 में बनाए गए dll पर ब्राउज़ करके ClassLibrary1 का संदर्भ जोड़ें।
  6. फिर से बनाएँ (ध्यान दें: यदि आप दोनों परियोजनाओं में बदलाव करते हैं, तो आपको दोनों संदर्भों को "ताज़ा" बनाने के लिए दो बार निर्माण करना होगा।

तो यह है कि आप इसे कैसे करते हैं। लेकिन गंभीरता से ... क्या आप इसे वास्तविक परियोजना में नहीं करते हैं! यदि आप करते हैं, तो सांता आपको इस वर्ष कोई भी उपहार नहीं लाएगा।


1
एकमात्र अपवाद यदि यह 26-31 दिसंबर के बीच का है और प्रस्तुत पहले ही सुरक्षित हो चुका है
जेसी हफस्टेलर

6

मुझे लगता है कि यह असेंबलियों के एक चक्रीय सेट के साथ शुरू करके और ILMerge का उपयोग करके छोटे असेंबली को तार्किक रूप से संबंधित समूहों में एकत्रित करने के लिए किया जा सकता है।


4

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

इसलिए यदि आपके पास दो पुस्तकालय हैं, तो A और B को एक दूसरे को संदर्भित करने की आवश्यकता है, कुछ इस तरह की कोशिश करें:

  1. लिंक A, B को बिना किसी भी लिंक के
  2. लिंक B के साथ ए के लिए refs
  3. लिंक ए, बी में रेफ को जोड़कर।

Dykam एक अच्छा बिंदु बनाता है, यह संकलन है, .net में लिंक नहीं है, लेकिन सिद्धांत समान रहता है: अपने क्रॉस-रेफ़र किए गए स्रोतों को, उनके निर्यात किए गए प्रवेश बिंदुओं के साथ बनाएं, लेकिन सभी के साथ लेकिन उनमें से एक ने दूसरों के लिए अपने स्वयं के संदर्भों को जताया बाहर। उन्हें ऐसा बनाएँ। फिर, बाहरी संदर्भों को अनस्टब करें और उनका पुनर्निर्माण करें। यह किसी भी विशेष उपकरण के बिना भी काम करना चाहिए, वास्तव में, इस दृष्टिकोण ने हर ऑपरेटिंग सिस्टम पर काम किया है जो मैंने कभी भी इस पर (लगभग 6) की कोशिश की है। हालांकि स्पष्ट रूप से कुछ है जो इसे स्वचालित करता है एक बड़ी मदद होगी।


प्रमेय सही है। हालाँकि .Net दुनिया में, लिंकिंग को डायनेमिक किया जाता है न कि कोई समस्या। यह संकलन कदम है जहाँ इस समाधान की आवश्यकता है।
Dykam

आपको फिर से ठीक करने के लिए क्षमा करें: पी। लेकिन संकलन समय पर संदर्भित (लिंकिंग) नेट दुनिया में होता है, जो कि सब कुछ है जो उस विशिष्ट ईसीएमए कल्पना से प्राप्त होता है। इस प्रकार मोनो, डॉट जीएनयू और .नेट। विंडोज ही नहीं।
Dykam

1

एक संभावित दृष्टिकोण पहली बार System.dll को संकलित करने के लिए सशर्त संकलन (#if) का उपयोग करना है जो उन अन्य विधानसभाओं पर निर्भर नहीं करता है, फिर अन्य असेंबली को संकलित करें, और अंतिम recompile System.dll पर Xml के आधार पर भागों को शामिल करने के लिए विन्यास।


1
दुर्भाग्य से यह आपको सशर्त रूप से एक असेंबली का संदर्भ देने की अनुमति नहीं देता है (मैं चाहता हूं कि यह संभव था, यह वास्तव में मेरी एक परियोजना में मदद करेगा ...)
थॉमस लेवेस्क

1
.Csproj फ़ाइल को संपादित करके सशर्त संदर्भ आसानी से किया जा सकता है। बस <Reference> तत्व में एक शर्त विशेषता जोड़ें।
डैनियल

0

तकनीकी रूप से, यह संभव है कि ये बिल्कुल संकलित नहीं किए गए थे, और हाथ से इकट्ठे हुए थे। ये निम्न स्तर के पुस्तकालय हैं, आखिरकार।


ज़रुरी नहीं। इसमें कई निम्न स्तर का सामान नहीं है, केवल बुनियादी है। आपको क्या लगा कि यह निम्न स्तर का होगा? रनटाइम और कॉर्लिब निम्न स्तर है। अपेक्षाकृत। फिर भी सादा C या C ++, सोचा कि JIT में निम्न स्तर का सामान है।
डाइकैम
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.