2009-01-19 9 views
5

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

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

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

इसके अलावा, यह आईआईएस के लिए प्रासंगिक है। आईआईएस में एक छाया प्रतिलिपि सेटिंग है जो निष्पादन असेंबली को स्मृति में लोड होने पर ओवरराइट करने की अनुमति देती है। समस्या यह है कि (कम से कम XP के तहत, उत्पादन 2003 सर्वर पर परीक्षण नहीं किया गया) जब आप प्रोग्रामेटिक रूप से एक असेंबली लोड करते हैं, तो छाया प्रतिलिपि काम नहीं करती है (क्योंकि आप डीएलएल लोड कर रहे हैं, आईआईएस नहीं)।

उत्तर

8
  1. जांचें कि असेंबली पहले ही लोड हो चुकी है (उसी असेंबली को बार-बार लोड करके होने वाली मेमोरी लीक से बचने के लिए)।
  2. यदि यह लोड नहीं हुआ है, तो असेंबली को बाइट सरणी में पढ़ें। यह फ़ाइल को लॉक करने से रोक देगा।
  3. आपूर्ति एक तर्क के रूप में बाइट सरणी

निम्नलिखित कोड मानता है कि आपके एक विधानसभा का FullName पता Assembly.Load करने के लिए।

Assembly assembly = null; 

foreach(Assembly loadedAssembly in AppDomain.CurrentDomain.GetAssemblies()) 
    if (loadedAssembly.FullName == "foobar, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null") 
     assembly = loadedAssembly; 

if(assembly == null) 
{ 
    byte[] studybin = System.IO.File.ReadAllBytes(@"C:\pathToAssembly\foobar.dll"); 
    assembly = Assembly.Load(studybin);     
} 

कि यदि आप एक निर्देशिका में एक विशिष्ट विधानसभा खोजने की कोशिश कर रहे हैं, आप चला सकते हैं नोट 'System.Reflection.AssemblyName.GetAssemblyName (पथ),' यह देखने के लिए कि क्या फुलनाम आप जो खोज रहे हैं उससे मेल खाता है। 'GetAssemblyName (पथ)' आपके वर्तमान ऐपडोमेन में असेंबली इंजेक्ट नहीं करता है।

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

+0

मुझे लगता है इसका मतलब है आप अभी भी एक बार यह डिस्क पर प्रतिस्थापित किया गया में नए प्लग का उपयोग करने के अनुप्रयोग पुनः आरंभ करना चाहते हैं? मैं इस धारणा के तहत था कि एक बार एक प्रकार लोड हो जाने पर इसे बदला नहीं जा सकता है, भले ही आप असेंबली को फिर से लोड करें। –

+3

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

2

आप अपने addins को अलग करना चाहते हैं, तो आपको ...

  1. एक प्रकार है कि MarshallByRefObject फैली जो अपने addins के साथ बातचीत करेंगे बनाएँ (कॉल की सुविधा देता है यह FOOMASTER)
  2. एक नया बनाएं एपडोमेन (इसे एडिनलैण्ड पर कॉल करें)
  3. कॉल एडिनलैण्ड। को CreateInstanceAndUnwrap अपने addins

अब आप अपने addins addinLand में लोड किए गए हैं लोड करने के लिए addinLand में FOOMASTER का एक उदाहरण बना सकते हैं और वर्तमान एप्लिकेशन डोमेन

  • बताएँ FOOMASTER में एक प्रॉक्सी मिलता है और आप से उन लोगों के साथ बातचीत कर सकते हैं आपके प्राथमिक एपडोमेन आपके फोमस्टर प्रॉक्सी के माध्यम से। जब आपके एडिन दुर्घटनाग्रस्त हो जाते हैं, तो वे आपके आवेदन को नहीं लेते हैं।

    यह एक दिलचस्प और थोड़ा भ्रमित प्रक्रिया है। मैंने मूल रूप से सोचा था कि विचार आपके एडिन को लोड करना था और फिर उन्हें मौजूदा ऐप डोमेन में पारदर्शी प्रॉक्सी के रूप में ले जाना था, लेकिन सबसे अच्छा डिज़ाइन एडिन को सरल ऑब्जेक्ट्स के रूप में छोड़ना है जो आपके द्वारा बनाए गए अधिक जटिल प्रकारों (फोमस्टर) के साथ बातचीत करते हैं, जो विस्तारित करते हैं MarshallByRefObject, जो addinLand ऐप डोमेन में लोड होते हैं, और जिनके पारदर्शी प्रॉक्सी आप के साथ बातचीत करते हैं।

    CLR Via C# के अध्याय 21 और 22 प्रक्रिया को समझने में बहुत उपयोगी हैं।

  • 2

    यदि आप प्लगइन आर्किटेक्चर के साथ सिस्टम बनाने के लिए एक गंभीर विधि में रूचि रखते हैं, तो आप एमएएफ (प्रबंधित एड-इन फ्रेमवर्क) को देखना चाहेंगे, जो अब .NET Framework, अर्थात् सिस्टम का हिस्सा है। AddIn नामस्थान।

    यह आपको एड-इन अलगाव और वर्जनिंग, अनुबंधों के साथ पिछड़ा संगतता प्रबंधित करने में सहायता करेगा।

    यद्यपि यहां एक सीखने की वक्र है, इसलिए यह वही नहीं हो सकता है जिसे आप ढूंढ रहे हैं।

    http://msdn.microsoft.com/en-us/library/bb384200.aspx

    संबंधित मुद्दे