2012-09-26 38 views
11

पर ओवरराइट कर सकूं। मैं अपने एमईएफ प्लगइन निर्देशिका में डीएलएल को लॉक करने के लिए अपने एप्लिकेशन को रोकने की कोशिश कर रहा हूं ताकि मैं रनटाइम पर असेंबली को ओवरराइट कर सकूं (नोट मैं वास्तव में एमईएफ रीलोड करने की कोशिश नहीं कर रहा हूं फ्लाई पर, अगली ऐप शुरू होने पर, मैं सिर्फ ऐप को कॉपी करने के लिए नहीं रोकना चाहता हूं)MEF और ShadowCopying DLLs ताकि मैं उन्हें रनटाइम

मैं अपने मेफ लोडेड असेंबली के लिए छाया प्रतिलिपि ऐप डोमेन बनाकर ऐसा करने की कोशिश कर रहा हूं नीचे के रूप में:

[Serializable] 
    public class Composer:IComposer 
    { 
     private readonly string _pluginPath; 
     public Composer(IConfigurePluginDirectory pluginDirectoryConfig) 
     { 
      _pluginPath = pluginDirectoryConfig.Path; 
      var setup = new AppDomainSetup(); 
      setup.ShadowCopyFiles = "true"; // really??? is bool not good enough for you? 
      var appDomain = AppDomain.CreateDomain(AppDomain.CurrentDomain.FriendlyName + "_PluginDomain", AppDomain.CurrentDomain.Evidence, setup); 

      appDomain.DoCallBack(new CrossAppDomainDelegate(DoWorkInShadowCopiedDomain));  
     } 

     private void DoWorkInShadowCopiedDomain() 
     { 
      // This work will happen in the shadow copied AppDomain. 

      var catalog = new AggregateCatalog(); 
      var dc = new DirectoryCatalog(_pluginPath); 
      catalog.Catalogs.Add(dc); 
      Container = new CompositionContainer(catalog); 
     } 

     public CompositionContainer Container { get; private set; } 
    } 

और उसके बाद इस वर्ग पर CompositionContainer के माध्यम से मेरे MEF घटक सूची तक पहुंचें। हालांकि संरचना कंटेनर केवल छायाकोपी डोमेन (जो समझ में आता है) के अंदर शुरू किया जाता है और इसका मतलब है कि यह मेरे आवेदन डोमेन में शून्य है। मैं बस सोच रहा था कि क्या मेरे एमईएफ घटकों को पाने के लिए ऐसा करने का कोई बेहतर तरीका है या डोमेन क्वेरी को पार करने का कोई तरीका है

+2

ऐसा लगता है कि आप अपनी मैन्युअल रूप से बनाई गई छाया निर्देशिका का उपयोग करके प्लगइन निर्देशिका में सभी फ़ाइलों पर फ़ाइल.कॉपी को बस कॉल कर सकते हैं। फिर आप अपने मुख्य डोमेन में छाया पथ से बस लोड हो जाते हैं। –

+0

मैंने इसके बारे में सोचा लेकिन मेरी समझ यह है कि यह समस्या है कि छाया प्रतिलिपि को हल करना है (इसलिए उनके पास संभवतः अधिक किनारे के मामले शामिल हैं)। क्या आपको पता है कि छाया छायांकन सिर्फ इतना ही बड़ा है या प्रतिलिपि मैन्युअल रूप से पर्याप्त कर रहा है? –

+0

@DanBryant मुझे प्राप्त उत्तरों के आधार पर मुझे लगता है कि यह हमारे लिए सबसे अच्छा समाधान है, अगर आप इसे बक्षीस समाप्त होने से पहले उत्तर के रूप में पोस्ट करते हैं तो मैं आपको बक्षीस दूंगा। –

उत्तर

-2

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

आप उन्हें फ्लाई पर लोड करने की क्षमता खो देंगे, लेकिन जैसा कि आपने बताया है कि वास्तव में एक आवश्यकता नहीं है।

+0

अरे @ zync शायद मुझे याद आ रहा है कि आप क्या मतलब कर रहे हैं लेकिन मैं अपनी खुद की DirecoryCatalog लागू करके छाया प्रतिलिपि/क्रॉस ऐप-डोमेन समस्या के आसपास कैसे हो सकता हूं। क्या इसे एक अलग ऐप डोमेन से खींचने के लिए कहने का कोई तरीका है? शायद आप –

+0

@LukeMcGregor के बारे में कुछ और विवरण जोड़ सकते हैं - मेरा सुझाव काम नहीं करेगा। लेकिन मैंने कुछ खोदने लगा और यह विशेष रूप से एक एमईएफ मुद्दा नहीं है। एपडोमेन किसी भी छूटी असेंबली को लॉक कर रहा है। http://stackoverflow.com/questions/2745093/overwriting-dlls-in-mef –

+0

हाँ आप सही हैं मेरी समस्या विशेष रूप से एक एमईएफ मुद्दा नहीं है यह एक छाया प्रति/एपडोमेन मुद्दा है। –

-1

यह परिदृश्य मोबाइल ऐप्स में ऑटो अपडेट सुविधा के करीब है। ऐप स्टार्ट/रीस्टार्ट पर उपलब्ध होने पर अनिवार्य रूप से आप नई असेंबली चुनना चाहते हैं।

यह डिज़ाइन करने का एक तरीका आपके ऐप को सिग्नल करने के लिए एक संचार तंत्र होना चाहिए ताकि नई असेंबली उपलब्ध हो (शायद एक संस्करण.txt फ़ाइल)। यदि हां, तो वही संस्करण.txt फ़ाइल असेंबली के नए स्थान पर इंगित कर सकती है। हां - आप सही संस्करण को इंगित करने के लिए कई उप फ़ोल्डरों को बना सकते हैं, लेकिन इन्हें किसी अन्य प्रक्रिया द्वारा साफ़ किया जा सकता है।

तुम इतनी तरह एक hierarchichal संरचना इस्तेमाल कर सकते हैं -

संस्करण \ - Version1.0 \ - Version2.0 \

इस डिजाइन के प्रकार के ऑटो अपडेट की एक अच्छी तरह से पता प्रतिमान के करीब होगा ।

+0

इसे एक नए उत्तर के रूप में जोड़ा क्योंकि यह विशिष्ट समस्या के बजाय समग्र समस्या को हल करने के लिए एक अलग दृष्टिकोण है। –

+0

मुझे लगता है कि जिस दृष्टिकोण का आप सुझाव दे रहे हैं वह वैन ब्रायंट्स के पहले सुझाव के समान है, मैन्युअल रूप से छाया प्रतिलिपि के समान कार्य करने के लिए। मैं इसे एक छोटे से हैकी महसूस कर रहा हूं क्योंकि यह मूल रूप से मौजूदा .NET फ़ंक्शन को क्लोन कर रहा है। मैं बस यह सुनिश्चित करने से पहले यह सुनिश्चित करना चाहता हूं कि क्रॉस डोमेन पहुंच के आसपास होने का कोई अच्छा तरीका न हो। –

3

यदि आप दान ब्रायंट और zync से समाधान का पालन नहीं करना चाहते हैं, तो आप एक शेल एप्लिकेशन बना सकते हैं जो आपके आवेदन को नए AppDomain में निष्पादित करता है।

एक दृष्टिकोण होगा:

  1. एक नया आवेदन परियोजना जो खोल आवेदन किया जाएगा बनाएँ।
  2. शैल एप्लिकेशन में, AppDomain बनाएं, छाया प्रतिलिपि सक्षम करें और यदि आप चाहें, तो निर्देशिका निर्दिष्ट करें जहां छाया प्रतिलिपि सक्षम की जाएगी।
  3. अपने वर्तमान एप्लिकेशन को कॉल करने के लिए AppDomain.ExecuteAssembly का उपयोग करें।

तो एक आवेदन के बजाय आप एक वर्ग पुस्तकालय आप निम्नलिखित की कोशिश कर सकते हैं:

  1. एक नया वर्ग पुस्तकालय परियोजना बनाएँ।
  2. नया वर्ग पुस्तकालय परियोजना के लिए निम्न इंटरफ़ेस जोड़ें:

    public interface IRemoteLoader 
    { 
        void Load(); 
        void Unload(); 
    } 
    
  3. एक नया AppDomain में अमल करने की जरूरत है कि अपने वर्ग पुस्तकालय को यह इंटरफ़ेस के एक कार्यान्वयन जोड़ें। Load और Unload विधियों में क्रमशः प्रारंभिकरण और सफाई करने के लिए आपको कोड जोड़ना चाहिए। वर्ग को MarshalByRefObject से प्राप्त करें। AppDomains दोनों पर प्रॉक्सी ऑब्जेक्ट्स बनाने के लिए .NET Remoting के लिए यह आवश्यक है।

  4. आप नए AppDomain बनाने के बाद, कदम से लोडर वर्ग का एक उदाहरण बनाने के लिए CreateInstanceAndUnwrap का उपयोग 3.

  5. कदम 4.

से बनाए वस्तु पर Load और Unload का प्रयोग करें

यह पर्याप्त होगा यदि आप जुर्माना नियंत्रण नहीं करते हैं और बस शुरू/रोकना पर्याप्त है।

+0

@panosrontogainnis हाँ मैं मानता हूं कि यह समस्या को हल करने का सबसे समर्थित तरीका है (यानी बूटस्ट्रैप/छायांकन पूरी एप्लिकेशन। दुर्भाग्यवश मेरे मामले में मैं बूटस्ट्रैप को नियंत्रित नहीं करता (जैसा कि मैं NServiceBus.Hosted में हूं) तो यह समाधान मेरे लिए विशेष रूप से काम नहीं करेंगे। ऐसा कहकर मुझे लगता है कि यह शायद दूसरों के लिए सबसे अच्छा समाधान है। –

+0

चीयर्स। मैंने एक और दृष्टिकोण जोड़ा जो कक्षा पुस्तकालयों के साथ काम करता है। –