लिंक करने पर .dll फ़ाइलों का उपयोग करने के लाभ।


38

मेरे पास एक सहायक परियोजना है जिसका उपयोग मैं उन सभी अनुप्रयोगों में करता हूं जो मैं बनाता हूं। इसमें कुछ विस्तार विधियां और सामान्य सहायक वर्गों का एक गुच्छा, नियंत्रण आदि शामिल हैं। मैं समय-समय पर सहायक परियोजना को अद्यतन / विस्तारित करता हूं। ये आमतौर पर छोटी और असंबंधित परियोजनाएं हैं, और मैं उन सभी पर काम करने वाला एकमात्र व्यक्ति हूं।

मैंने इसका उपयोग करने के लिए दो तरीकों की कोशिश की

  • प्रत्येक प्रोजेक्ट में .cs फाइलें सीधे (लिंक के रूप में जोड़ें) जोड़ें जहां मैं उनका उपयोग करता हूं
  • इसे .dll के रूप में संकलित करें और इसे संदर्भ के रूप में जोड़ें

मुझे इन दृष्टिकोणों के कुछ लाभ और कमियां दिखाई देती हैं।
पहले वाला:

  • सरल है, क्योंकि हेल्पर कक्षाएं एक्सई फ़ाइल में संकलित हो जाती हैं, इसलिए मैं अक्सर बहुत आसानी से सिर्फ एक .exe फ़ाइल प्रदान कर सकता हूं जो बस ठीक काम करेगा। क्योंकि मैं लिंक के रूप में जोड़ता हूं, मुझे पूरा यकीन है कि जब भी मैं किसी भी प्रोजेक्ट का निर्माण करता हूं जो हेल्पर का उपयोग करता है, तो हेल्पर फाइलें नवीनतम संस्करण होंगी।
  • और भी सरल है, क्योंकि मैं फ़ाइलों को अलग कर सकता हूं, ताकि .NET 4.0 पर ठीक चलने वाले मेरे एक्सटेंशन तरीकों को .NET 4.5 की आवश्यकता वाले लोगों से अलग से संदर्भित किया जा सके, जिसका अर्थ है कि संपूर्ण के रूप में ऐप .NET 4.0 पर चल सकता है
  • ब्रेकपाइंट आदि के सभी लाभों के साथ कोड के माध्यम से डिबग करने की अनुमति देता है ...
  • नहीं लगता है 'सबसे अच्छा अभ्यास'

दूसरा एक:

  • सही दृष्टिकोण प्रतीत होता है, लेकिन:
  • मुझे एक अलग .dll फ़ाइल देने की आवश्यकता है, जो किसी कारण से उपयोगकर्ताओं के लिए बहुत अधिक कठिन है (वे .dll के बिना मेरे कार्यक्रमों को साझा करते हैं, जो तब स्टार्टअप पर क्रैश हो जाते हैं)
  • क्योंकि यह एक एकल .dll में संकलित हो जाता है, इसे .NET के उच्चतम संस्करण की आवश्यकता होगी - मेरे कई उपयोगकर्ताओं के पास .NET 4.5 नहीं है और केवल मेरे सहायक वर्ग के कुछ तत्वों को इसकी आवश्यकता है, जिसका अर्थ है कि मैं कुछ लोगों को मजबूर कर सकता हूं बिना किसी कारण के उनके सिस्टम को अपडेट करने के लिए
  • मुझे यह भी सुनिश्चित करने की आवश्यकता है कि जब भी मैं अपने किसी भी प्रोग्राम को अपडेट करता हूं, मैं भी .dll फ़ाइल वितरित करता हूं - भले ही मुझे नहीं पता कि यह पिछले संस्करण के बाद से बदल दिया गया है, या नहीं (यह हो सकता था, लेकिन यह के रूप में अच्छी तरह से एक ही संस्करण हो सकता है)। मैं विधानसभा संस्करण का ट्रैक रखे बिना, यह निर्धारित करने का एक सरल तरीका नहीं देख सकता, जो अतिरिक्त काम है। अभी के लिए, जब मैं अपने प्रोग्राम्स को अपडेट करता हूं, तो मैं केवल अपडेटेड एक्सई डिलीवर करता हूं, और मैं इसे छोटा और लो प्रोफाइल रखना पसंद करता हूं।

तो, यहाँ .dll फ़ाइल का उपयोग करने के लिए वास्तविक लाभ क्या है? कृपया ध्यान दें, कि मैं सभी एप्लिकेशन और हेल्पर फ़ाइलों का एकमात्र व्यक्ति संपादन कोड हूं।


इसके अलावा, स्पष्ट करने के लिए - एप्लिकेशन आमतौर पर बहुत कम होते हैं, जबकि सहायक वर्गों में निहित कोड उन सभी के लिए पूरी तरह से सामान्य है (कुछ सरल स्ट्रिंग-तुलना, पथ या एक्सएमएल संचालन आदि)


दरअसल, किसी ने मुझे एहसास कराया कि अभी तीसरा विकल्प है। जैसा कि मेरे पास एक सेपरेट प्रोजेक्ट में सहायक कोड है, मैं इस परियोजना को अपने प्रत्येक अलग-अलग अनुप्रयोगों के समाधान में जोड़ सकता हूं - जो एकल फ़ाइलों के लिए 'एड के रूप में लिंक' की तरह काम करता है, सिवाय इसके कि मैं केवल एक ही प्रोजेक्ट जोड़ूं ... लेकिन जैसा कि डॉक्टर ब्राउन ने देखा है, इसका अनिवार्य रूप से मतलब है कि .dll को वैसे भी प्रोजेक्ट में जोड़ना होगा ...

फिर भी एक और बात जो dll फ़ाइलों का उपयोग न करने के पक्ष में है, सहायक वर्ग के माध्यम से सक्रिय रूप से डिबग करने की क्षमता है ...


3
आप सही हैं, और मैं इसे भी कर रहा हूं, क्योंकि यह उच्च .NET आवश्यकताओं के मामले में मदद करता है ... लेकिन मुझे यह करना पसंद नहीं है ... 40kb ऐप के लिए एक इंस्टॉलर एक ओवरकिल का एक सा है :)
बार्टोज़

3
वैसे आप कोस्टुरा जैसी चीज का हमेशा उपयोग कर सकते हैं , यह DLL को मर्ज करने का एक उपकरण है। आप सभी निर्भरताएँ EXE में मर्ज कर सकते हैं, एक भी फ़ाइल रख सकते हैं और आपको आवश्यक किसी भी लाइब्रेरी का उपयोग करने की अनुमति दे सकते हैं। यह सरलता के लिए, निर्माण प्रक्रिया के लिए स्वचालित हो सकता है।
क्राल्टन

2
जब आप किसी समाधान के लिए एक परियोजना जोड़ते हैं, तो आपको अभी भी इस परियोजना के DLL को तैनात करना होगा, ऊपर सूचीबद्ध सभी कमियों के साथ।
डॉक ब्राउन

2
@DocBrown - पवित्र बकवास, आप सही :)
बार्तोज़

1
लिंक .cs फ़ाइलों या प्रोजेक्ट्स में एक और कमी हो सकती है। यदि आप इन साझा फ़ाइलों का कई परियोजनाओं में उपयोग कर रहे हैं, और एक परियोजना के लिए आपके साझा पुस्तकालयों में परिवर्तन की आवश्यकता है, तो आपको अब अन्य परियोजनाओं को फिर से तैयार करने की आवश्यकता है। रेफ़रलिंग dlls आपको इससे प्रेरित करते हैं कि यदि आपके कोड के लिए कोई कारण नहीं है कि अद्यतन तर्क की आवश्यकता हो। मैं उन विकास टीमों का हिस्सा रहा हूँ जो इस मुद्दे पर चल चुकी हैं जब साझा परियोजनाओं में कस्टम प्रमाणीकरण जैसी चीज़ें शामिल हैं। ग्राहक एक नए अनुप्रयोग के लिए एक बदलाव की कोशिश करना चाहता है, और अब आपको किसी भी तरह से अपने सामान्य पुस्तकालय को संस्करणित करने की आवश्यकता है। Dlls का उपयोग करना।
एल्सडिल

जवाबों:


13

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

अलग DLL का उपयोग करना

  • अन्य उपयोगिताओं या पुस्तकालयों के लिए निर्भरता को स्पष्ट करेगा (जब तक आपके पास ऐसी निर्भरता नहीं है, यह ठीक काम करेगा)

  • आपको विशिष्ट बिल्ड कॉन्फ़िगरेशन को परिभाषित करने की अनुमति देगा (उदाहरण के लिए, यदि कोई वर्ग केवल x86 कॉन्फ़िगरेशन में काम करता है, या कम से कम .NET 4.0 की आवश्यकता है, तो विधानसभा का बिल्ड कॉन्फ़िगरेशन इस आवश्यकता को स्पष्ट करता है)।

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

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


ठीक है, बहुत बहुत धन्यवाद - तो, ​​क्या मैं सही ढंग से समझता हूं, कि जब तक मेरे सहायक वर्ग किसी भी अन्य बाहरी dll (केवल मानक .NET कोड शामिल नहीं हैं) का संदर्भ नहीं देते हैं, यह केवल उन्हें लिंक करने के लिए एक घृणा नहीं है?
बार्टोज़ सिप

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

1
@PeterK। - हाँ, और मैंने किया :)
बार्टोज़

1
@whatsisname: ऐसा नहीं है कि यह काम नहीं कर सकता। हालाँकि, मेरे लिए यह एक समाधान की तरह नहीं है, जो चीजों को सरल बना देगा, एक से अधिक जो अप्रत्याशित समस्याओं का कारण बन सकता है ;-)
डॉक्टर ब्राउन

1
@Ozkan: हमारे वातावरण में, यह सिर्फ कुछ नेटवर्क शेयर (पूर्व संस्करण का बैकअप लेने के लिए कुछ अतिरिक्त चरणों के साथ और वर्तमान में कोई भी प्रोग्राम का उपयोग करता है - जो कि पहले तैनाती फ़ोल्डर का नाम बदलने के प्रयास से प्राप्त होता है) के लिए सिर्फ xcopy परिनियोजन है। यह जानता है कि कौन सी तैनाती करना है क्योंकि हम स्क्रिप्ट में आवश्यक DLL की सूची को हार्डकोड करते हैं - इसके पीछे कोई जादू नहीं है। यह समाधान सही नहीं है, लेकिन हमारे लिए ज्यादातर मामलों में काम करता है, केवल उन कार्यक्रमों को छोड़कर जो दर्जनों उपयोगकर्ताओं द्वारा भारी उपयोग किए जाते हैं।
डॉक्टर ब्राउन

11

जब कोई एप्लिकेशन बड़ा होता है तो DLL आसान होते हैं और ऐसे टुकड़े होते हैं जिन्हें अपडेट की आवश्यकता होती है, लेकिन संपूर्ण एप्लिकेशन की नहीं। इसलिए, यदि आप MS Word लिख रहे हैं, तो एक DLL में वर्तनी-जांच कोड होना आसान है जिसे MS Word की संपूर्णता को अपडेट किए बिना अपडेट किया जा सकता है। यदि आप जो लिख रहे हैं, वह एक छोटी सी उपयोगिता ऐप (या स्व-सम्‍मिलित ऐप्‍स की श्रृंखला है जो सभी समान कोड का उपयोग करते हैं) तो इससे बहुत फर्क नहीं पड़ता कि कोड ऐप (ओं) में अंतर्निहित है या नहीं।


2

आपने अपने प्रश्न में इसे बहुत अधिक अभिव्यक्त किया है, मेरे पास जोड़ने के लिए केवल कुछ बिंदु हैं।

मोनो विकल्प एक NuGet पैकेज का एक शानदार उदाहरण है जो पहले दृष्टिकोण का बहुत अच्छी तरह से उपयोग करता है।

वैकल्पिक रूप से, यदि आप dlls का उपयोग करने का निर्णय लेते हैं, तो आप कॉस्टुरा जैसे टूल का उपयोग उस सन्दर्भ में एम्बेडेड संसाधन के रूप में करने के लिए कर सकते हैं । इसका उपयोग करने के लिए बस Costura.Fodyपैकेज जोड़ें :

Install-Package Costura.Fody

वास्तव में, एक और बात है - एम्बेडेड प्रोजेक्ट या लिंक के रूप में फाइल के साथ, आप सक्रिय रूप से कोड को हेल्पर फ़ाइल के माध्यम से सभी तरह से डिबग कर सकते हैं ...
बार्टोज़ सिप

1
@Bartosz मुझे लगता है कि आप अभी भी "हेल्पर फ़ाइल" के बिना "सभी तरह से" डिबग कर सकते हैं, जब तक कि आपके पास सही पीडीबी फ़ाइल है।
ज़ैक

मैंने कॉस्ट्यूरा चीज़ की कोशिश की और मुझे यह बहुत पसंद है!
बार्टोज़

2

एक dll अधिक लाभदायक है या नहीं यह कई कारकों पर निर्भर करता है:

  1. कोड का आकार (जब संकलित)।
  2. कितने एक्सईज इसका इस्तेमाल करते हैं।
  3. आप कितनी बार कोड अपडेट करने का इरादा रखते हैं।
  4. निर्वासन को एक साथ रखने का इरादा है या नहीं या पूरी तरह से अलग मौजूद हैं।

एक साझा पुस्तकालय का उद्देश्य ऐसे कोड लेना है जो कई निष्पादन योग्य के लिए सामान्य है और इसे केंद्रीकृत किया गया है ताकि सभी निष्पादन योग्य एक प्रतिलिपि साझा करें। यह अंतरिक्ष को बचाने और कोड को अद्यतन करने के लिए आसान बनाने का इरादा है।

यदि आपके सहायक वर्ग में कोड की मात्रा बहुत कम है, तो यह इसे एक dll में ले जाने के लायक नहीं हो सकता है क्योंकि कोड का ओवरहेड एक dll में होने के कारण यह केंद्रीय बचत होने के स्थान बचत लाभ का प्रतिकार कर सकता है।

इसके अतिरिक्त, यदि आप केवल कुछ निष्पादन योग्य बना रहे हैं, तो प्रत्येक निष्पादन योग्य में कोड का आकार एक समस्या न होने के लिए छोटा हो सकता है। हालाँकि, आपके पास एक ही कोड का उपयोग करने वाले अधिक निष्पादन योग्य हैं, यह उतना ही फायदेमंद होगा जितना कि कोड एक dll में चला गया हो।

एक सरलीकृत उदाहरण के रूप में, मान लें कि आपकी सहायक कक्षा एक एक्साई फ़ाइल में 128 बाइट्स का संकलन करती है, लेकिन जब एक dll में ले जाया जाता है, तो dll 512 बाइट्स होता है। यदि आपके पास केवल 3 निष्पादनयोग्य हैं, तो आप निष्पादनयोग्य में कोड को शामिल करके स्थान की बचत करेंगे। हालाँकि, यदि आपके पास 5 निष्पादनयोग्य होते हैं, तो आप उस बिंदु पर होंगे जहां आप एक dll होने से बेहतर होंगे क्योंकि कोड की 5 प्रतियों (5 * 128 = 640 बाइट्स) द्वारा संयुक्त स्थान ऊपर उठाए गए स्थान से अधिक है एक dll (512 बाइट्स) में कोड होने से।

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

अंत में, एक dll को खोजने के लिए एक कार्यक्रम के लिए यह जानना होगा कि dll कहाँ देखना है। यदि आप अपने सभी निष्पादनों को एक साथ रख रहे हैं, तो आप केवल dll को उसी निर्देशिका में रख सकते हैं और वे सभी इसे सीधे पा लेंगे। यदि आप जानबूझकर उन्हें अलग कर रहे हैं, तो उन्हें उसी dll का उपयोग करने के लिए समन्वय करना कठिन हो जाता है।


1

आपका तीसरा विकल्प सबसे उपयुक्त है (इसे समाधान के लिए एक अलग "क्लास लाइब्रेरी" प्रोजेक्ट के रूप में जोड़ें)। यह सभी दृष्टिकोणों के लाभों को जोड़ती है:

  • आपकी "हेल्पर परियोजना" हमेशा सभी विभिन्न परियोजनाओं पर निर्भर रहती है।
  • जब आप जल्दी से बदलाव देखना चाहते हैं, तो आप परियोजना के कोड का संदर्भ दे सकते हैं।
  • आप इसे हर बार सही .NET संस्करण के लिए बना सकते हैं।
  • आप किसी भी तरह एक DLL को एम्बेड कर सकते हैं, इसलिए इस बात की चिंता न करें कि आपके पास आपके निर्माण के हिस्से के रूप में बस हो सकता है।

हम यह हर समय करते हैं और मैं कुछ नहीं कर सकता लेकिन इस दृष्टिकोण की सिफारिश करता हूं।

एक और चौथा विकल्प जिसका आपने उल्लेख नहीं किया है, वह इसे एक निजी नुगेट रिपॉजिटरी पर रखना है जो आपको इसे सही ढंग से वर्जन करने देगा और प्रत्येक समाधान में अतिरिक्त प्रोजेक्ट के बिना इसे संदर्भित करेगा।


2
हम्म, यह मुझे प्रतीत होता है कि जब मैं इसे एक प्रोजेक्ट के रूप में समाधान में जोड़ता हूं और फिर अन्य प्रोजेक्ट में इस प्रोजेक्ट को संदर्भित करता हूं, तो यह अभी भी एक अलग के रूप में बनाया जाता है। एम्बेडेड होने के बजाय। क्या ... क्या मुझे निर्दिष्ट करना चाहिए?
बार्टोज़

1

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

इसलिए, वास्तव में निर्णय इस बात पर निर्भर करता है कि उपयोगिता कितनी परिपक्व है! यदि आप उपयोगिता बग के बारे में अनिश्चित हैं, तो आपको हमेशा बग्स का पता लगाने के लिए उस उपयोगिता की .cs फ़ाइल को शामिल करना चाहिए .. लेकिन यदि आप सुनिश्चित हैं कि उपयोगिता काफी परिपक्व है और यह किसी भी बग के साथ परिणाम नहीं लौटाएगा और उपयोगिता में वृद्धि की कोई गुंजाइश नहीं है, आप आगे जा सकते हैं और DLL फ़ाइल शामिल कर सकते हैं।

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