.NET में असेंबलियों का संस्करण देना एक भ्रामक संभावना हो सकती है, यह देखते हुए कि आपके विधानसभा के लिए एक संस्करण निर्दिष्ट करने के लिए वर्तमान में कम से कम तीन तरीके हैं।
यहाँ तीन मुख्य संस्करण-संबंधित विधानसभा विशेषताएँ हैं:
// Assembly mscorlib, Version 2.0.0.0
[assembly: AssemblyFileVersion("2.0.50727.3521")]
[assembly: AssemblyInformationalVersion("2.0.50727.3521")]
[assembly: AssemblyVersion("2.0.0.0")]
कन्वेंशन द्वारा, संस्करण के चार भागों को मेजर संस्करण , माइनर संस्करण , बिल्ड , और संशोधन के रूप में संदर्भित किया जाता है ।
AssemblyFileVersion
विशिष्ट के निर्माण की पहचान करने का इरादा है अलग-अलग विधानसभा
आमतौर पर आप मैन्युअल रूप से विधानसभा के संस्करण को प्रतिबिंबित करने के लिए मेजर और माइनर असेंबली फ़ाइलेवर सेट करेंगे, फिर हर बार जब आपका बिल्ड सिस्टम असेंबली को संकलित करता है, तो बिल्ड और / या संशोधन बढ़ाएँ। असेम्बलीफाइलवर्जन आपको असेंबली के निर्माण को विशिष्ट रूप से पहचानने की अनुमति देता है, ताकि आप इसे किसी भी समस्या को डीबग करने के लिए एक प्रारंभिक बिंदु के रूप में उपयोग कर सकें।
मेरी वर्तमान परियोजना पर, हमारे पास बिल्ड सर्वर है जो हमारे स्रोत नियंत्रण भंडार से चैंजिस्ट नंबर को असेंबली फ़ाइलवेशन के बिल्ड और रिविजन भागों में एन्कोड करता है। यह हमें एक असेंबली से सीधे अपने स्रोत कोड तक निर्माण सर्वर द्वारा उत्पन्न किसी भी विधानसभा के लिए (स्रोत नियंत्रण में लेबल या शाखाओं का उपयोग किए बिना, या मैन्युअल रूप से जारी किए गए संस्करणों के किसी भी रिकॉर्ड को रखने के लिए) करने की अनुमति देता है।
इस संस्करण संख्या को Win32 संस्करण संसाधन में संग्रहीत किया गया है और विधानसभा के लिए विंडोज एक्सप्लोरर संपत्ति पृष्ठों को देखते समय इसे देखा जा सकता है।
CLR असेंबली का ध्यान नहीं रखता है और न ही असेंबली फ़ाइलेविज़न की जाँच करता है।
AssemblyInformationalVersion
अपनी संपूर्ण उत्पाद के संस्करण का प्रतिनिधित्व करने का इरादा है
असेंबली इनफॉर्मेशनवैल्यूएशन का उद्देश्य पूरे उत्पाद के सुसंगत संस्करणकरण की अनुमति देना है, जिसमें कई विधानसभाएं शामिल हो सकती हैं जो स्वतंत्र रूप से भिन्न होती हैं, शायद अलग-अलग संस्करण नीतियों के साथ, और संभावित रूप से विषम टीमों द्वारा विकसित की जाती हैं।
“उदाहरण के लिए, किसी उत्पाद के संस्करण 2.0 में कई विधानसभाएं हो सकती हैं; इन विधानसभाओं में से एक को 1.0 संस्करण के रूप में चिह्नित किया गया है क्योंकि यह एक नई विधानसभा है जो उसी उत्पाद के संस्करण 1.0 में जहाज नहीं करता था। आमतौर पर, आप अपने उत्पाद के सार्वजनिक संस्करण का प्रतिनिधित्व करने के लिए इस संस्करण संख्या के प्रमुख और मामूली भागों को निर्धारित करते हैं। फिर आप प्रत्येक बार अपनी सभी विधानसभाओं के साथ एक पूर्ण उत्पाद का निर्माण करने के लिए निर्माण और संशोधन भागों को बढ़ाते हैं। " - जेफरी रिक्टर, [सीएलआर थ्रू सी # (दूसरा संस्करण)] पी। 57
CLR असेंबली के बारे में परवाह नहीं करता है और न ही जाँच करता है।
AssemblyVersion
केवल संस्करण है के बारे में CLR चिंताओं (लेकिन यह पूरी की परवाह करता है AssemblyVersion
)
असेंबली का उपयोग सीएलआर द्वारा दृढ़ता से नामित विधानसभाओं को बांधने के लिए किया जाता है। यह निर्मित असेंबली के असेंबली डिफॉल्ट मेटाडेटा तालिका में संग्रहीत किया जाता है, और किसी भी असेंबली की असेंबली टेबल में संदर्भ देता है।
यह बहुत महत्वपूर्ण है, क्योंकि इसका मतलब है कि जब आप एक दृढ़ता से नामित विधानसभा का संदर्भ देते हैं, तो आप कसकर उस विधानसभा के एक विशिष्ट विधानसभा में बंधे होते हैं। सफल होने के लिए पूरे असेंबली वर्जन को बाइंडिंग के लिए एक सटीक मिलान होना चाहिए। उदाहरण के लिए, यदि आप बिल्ड-टाइम में दृढ़ता से नामित असेंबली के 1.0.0.0 संस्करण का संदर्भ देते हैं, लेकिन रनिंग के समय उस असेंबली का केवल संस्करण 1.0.0.1 उपलब्ध है, तो बंधन विफल हो जाएगा! (आपको इसके बाद असेंबली बाइंडिंग रिडायरेक्शन का उपयोग करके काम करना होगा ।)
इस पर भ्रम है कि क्या पूरे AssemblyVersion
मैच के लिए है। (हाँ यह करता है।)
चारों ओर थोड़ा भ्रम है कि क्या पूरी विधानसभा को लोड करने के लिए एक विधानसभा के लिए सटीक मिलान होना चाहिए। कुछ लोग झूठी मान्यता के तहत हैं कि विधानसभा के केवल मेजर और माइनर हिस्सों को सफल होने के लिए बाध्य करने के लिए मिलान करना होगा। यह एक समझदार धारणा है, हालांकि यह अंततः गलत है (.NET 3.5 के रूप में), और यह CLR के आपके संस्करण के लिए इसे सत्यापित करने के लिए तुच्छ है। बस इस नमूना कोड को निष्पादित करें ।
मेरी मशीन पर दूसरी असेंबली लोड विफल रहता है, और फ़्यूजन लॉग की अंतिम दो पंक्तियाँ यह पूरी तरह स्पष्ट करती हैं कि क्यों:
.NET Framework Version: 2.0.50727.3521
---
Attempting to load assembly: Rhino.Mocks, Version=3.5.0.1337, Culture=neutral, PublicKeyToken=0b3305902db7183f
Successfully loaded assembly: Rhino.Mocks, Version=3.5.0.1337, Culture=neutral, PublicKeyToken=0b3305902db7183f
---
Attempting to load assembly: Rhino.Mocks, Version=3.5.0.1336, Culture=neutral, PublicKeyToken=0b3305902db7183f
Assembly binding for failed:
System.IO.FileLoadException: Could not load file or assembly 'Rhino.Mocks, Version=3.5.0.1336, Culture=neutral,
PublicKeyToken=0b3305902db7183f' or one of its dependencies. The located assembly's manifest definition
does not match the assembly reference. (Exception from HRESULT: 0x80131040)
File name: 'Rhino.Mocks, Version=3.5.0.1336, Culture=neutral, PublicKeyToken=0b3305902db7183f'
=== Pre-bind state information ===
LOG: User = Phoenix\Dani
LOG: DisplayName = Rhino.Mocks, Version=3.5.0.1336, Culture=neutral, PublicKeyToken=0b3305902db7183f
(Fully-specified)
LOG: Appbase = [...]
LOG: Initial PrivatePath = NULL
Calling assembly : AssemblyBinding, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null.
===
LOG: This bind starts in default load context.
LOG: No application configuration file found.
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework64\v2.0.50727\config\machine.config.
LOG: Post-policy reference: Rhino.Mocks, Version=3.5.0.1336, Culture=neutral, PublicKeyToken=0b3305902db7183f
LOG: Attempting download of new URL [...].
WRN: Comparing the assembly name resulted in the mismatch: Revision Number
ERR: Failed to complete setup of assembly (hr = 0x80131040). Probing terminated.
मुझे लगता है कि इस भ्रम का स्रोत शायद इसलिए है क्योंकि Microsoft मूल रूप से पूर्ण असेंबली वर्जन के इस सख्त मिलान पर थोड़ा और अधिक उदार होना चाहता था, केवल मेजर और माइनर संस्करण भागों पर मिलान करके:
"जब कोई असेंबली लोड कर रहा है, सीएलआर स्वचालित रूप से नवीनतम स्थापित सर्विसिंग संस्करण को खोज लेगा जो अनुरोध किए जा रहे असेंबली के प्रमुख / लघु संस्करण से मेल खाता है।" - जेफरी रिक्टर, [सीएलआर थ्रू सी # (दूसरा संस्करण)] पी। 56
यह 1.0 सीएलआर के बीटा 1 में व्यवहार था, हालांकि यह सुविधा 1.0 रिलीज से पहले हटा दी गई थी, और .NET 2.0 में फिर से सतह पर कामयाब नहीं हुई है:
"ध्यान दें: मैंने अभी वर्णन किया है कि आपको संस्करण संख्याओं के बारे में कैसे सोचना चाहिए। दुर्भाग्य से, सीएलआर इस तरह संस्करण संख्याओं का इलाज नहीं करता है। [.NET 2.0 में], CLR एक वर्जन संख्या को अपारदर्शी मान के रूप में मानता है, और यदि कोई असेंबली किसी अन्य असेंबली के संस्करण 1.2.3.4 पर निर्भर करती है, तो CLR केवल 1.2.3.4 संस्करण को लोड करने की कोशिश करता है (जब तक कि एक बाध्यकारी पुनर्निर्देशन नहीं होता है )। हालाँकि, Microsoft की भविष्य के संस्करण में CLR के लोडर को बदलने की योजना है ,
ताकि यह किसी विधानसभा के नवीनतम प्रमुख / मामूली संस्करण के लिए नवीनतम बिल्ड / संशोधन को लोड करे। उदाहरण के लिए, सीएलआर के भविष्य के संस्करण पर, यदि लोडर असेंबली के संस्करण 1.2.3.4 को खोजने की कोशिश कर रहा है और संस्करण 1.2.5.0 मौजूद है, तो लोडर स्वचालित रूप से नवीनतम सर्विसिंग संस्करण उठाता है। यह CLR के लोडर के लिए बहुत स्वागतयोग्य बदलाव होगा - मैं इंतजार नहीं कर सकता। " - जेफरी रिक्टर, [सीएलआर थ्रू सी # (दूसरा संस्करण)] पी। 164 (जोर मेरा)
जैसा कि यह परिवर्तन अभी भी लागू नहीं हुआ है, मुझे लगता है कि यह मानना सुरक्षित है कि Microsoft इस इरादे से पीछे हट गया था, और शायद अब इसे बदलने में बहुत देर हो चुकी है। मैंने इन योजनाओं के साथ क्या हुआ, यह जानने के लिए वेब के चारों ओर खोज करने की कोशिश की, लेकिन मुझे कोई उत्तर नहीं मिला। मैं अब भी इसकी तह तक जाना चाहता था।
इसलिए मैंने जेफ रिक्टर को ईमेल किया और उससे सीधे पूछा - मुझे लगा कि अगर किसी को पता चल गया कि क्या हुआ, तो वह वह होगा।
उन्होंने 12 घंटे के भीतर जवाब दिया, शनिवार की सुबह कम नहीं है, और स्पष्ट किया कि .NET 1.0 बीटा 1 लोडर ने विधानसभा के नवीनतम उपलब्ध बिल्ड और संशोधन को चुनने के इस 'स्वचालित रोल-फॉरवर्ड' तंत्र को लागू किया, लेकिन यह व्यवहार था .NET 1.0 शिप होने से पहले रिवर्ट किया गया। बाद में इसे पुनर्जीवित करने का इरादा था, लेकिन CLR 2.0 द्वारा शिप किए जाने से पहले इसे नहीं बनाया गया। इसके बाद सिल्वरलाइट आई, जिसने सीएलआर टीम के लिए प्राथमिकता तय की, इसलिए इस कार्यशीलता में और देरी हुई। इस बीच, CLR 1.0 Beta 1 के दिनों में आस-पास के अधिकांश लोग चले गए थे, इसलिए यह संभावना नहीं है कि यह दिन की रोशनी को देखेगा, इसके बावजूद सभी कड़ी मेहनत जो पहले से ही इसमें डाली गई थी।
वर्तमान व्यवहार, ऐसा लगता है, यहाँ रहने के लिए है।
जेफ के साथ मेरी चर्चा से यह भी ध्यान देने योग्य है कि असेंबलीफाइल वर्जन केवल 'स्वचालित रोल-फॉरवर्ड' तंत्र को हटाने के बाद जोड़ा गया था - क्योंकि 1.0 बीटा 1 के बाद, असेंबली वर्जन में कोई भी बदलाव आपके ग्राहकों के लिए एक परिवर्तन था, तब था कहीं भी सुरक्षित रूप से अपना बिल्ड नंबर न रखें। असेम्बलीफाइलवर्जन वह सुरक्षित आश्रय है, क्योंकि यह कभी भी सीएलआर द्वारा स्वचालित रूप से जांच नहीं की जाती है। हो सकता है कि यह उस तरह से स्पष्ट हो, जिसमें अलग-अलग अर्थों के साथ, दो अलग-अलग संस्करण संख्याएँ हों, बजाय कि मेजर / माइनर (ब्रेकिंग) और बिल्ड / रिविजन (नॉन-ब्रेकिंग) के अलग-अलग हिस्सों को बनाने का प्रयास करें।
नीचे की रेखा: जब आप अपने को बदलते हैं तो सावधानी से सोचें AssemblyVersion
नैतिक यह है कि यदि आप असेंबली को शिपिंग कर रहे हैं, जो अन्य डेवलपर्स को संदर्भित करने जा रहे हैं, तो आपको उन असेंबली के असेंबलीकरण को बदलने (और न करने) के बारे में बेहद सावधान रहने की आवश्यकता है। असेंबली में किसी भी बदलाव का मतलब यह होगा कि एप्लिकेशन डेवलपर्स को या तो नए संस्करण के खिलाफ (उन असेंबली रीफ को अपडेट करने के लिए) संकलन करना होगा या बाइंडिंग को मैन्युअल रूप से ओवरराइड करने के लिए असेंबली बाइंडिंग पुनर्निर्देश का उपयोग करना होगा।
- असेंबली रिलीज़ के लिए असेंबली वर्जन को न बदलें, जो पीछे की ओर संगत होने का इरादा रखता है।
- है एक रिलीज की आप जानते हैं कि तोड़ने परिवर्तन के लिए AssemblyVersion बदल जाते हैं।
बस mscorlib पर संस्करण विशेषताओं पर एक और नज़र डालें:
// Assembly mscorlib, Version 2.0.0.0
[assembly: AssemblyFileVersion("2.0.50727.3521")]
[assembly: AssemblyInformationalVersion("2.0.50727.3521")]
[assembly: AssemblyVersion("2.0.0.0")]
ध्यान दें कि यह असेंबली फ़ाइलव्यूशन है जिसमें सभी दिलचस्प सर्विसिंग जानकारी शामिल है (यह इस संस्करण का संशोधन भाग है जो आपको बताता है कि आप किस सर्विस पैक पर हैं), इस बीच असेंबली विचलन एक उबाऊ पुराने 2.0.0.0 पर तय किया गया है। असेंबलीव्यू में कोई भी बदलाव हर .NET एप्लिकेशन को नए संस्करण के खिलाफ पुनः संकलन करने के लिए mscorlib.dll संदर्भित करने के लिए मजबूर करेगा!