2013-07-11 8 views
5

में पुनर्वितरण तो, मैं एम्बेडेड संसाधनों से डीएलएल को रनटाइम पर प्लगइन में लोड करने के लिए AppDomain.CurrentDomain.AssemblyResolve के उपयोग के संदर्भ में कई लेखों से आया हूं (IlMerge के उपयोग के बिना)। हालांकि, जब मैं इस कोड को सम्मिलित करता हूं, तो प्लगइन से पहले ईवेंट हैंडलर को थ्रेड प्राप्त नहीं होता है, मेरी मुख्य लाइब्रेरी के लिए TypeLoadException संदेश फेंकता है।AppDomain.CurrentDomain.Assembly डायनेमिक्स सीआरएम

मैंने निष्पादन विधि के अंदर और मुख्य कन्स्ट्रक्टर में कोड को स्थिर कन्स्ट्रक्टर में रखने का प्रयास किया है; और यद्यपि ईवेंट हैंडलर पंजीकृत है, हैंडलर में ब्रेकपॉइंट हिट नहीं होते हैं।

पर्यावरण नवीनतम रोल अप के साथ डायनेमिक्स सीआरएम 2011 है और एसडीके डेवलपर टूल्स प्लगइन प्रोजेक्ट और प्लगइन क्लास पीढ़ी का उपयोग कर रहा है।

कोई भी जानता है कि इसे काम करने के लिए मुझे क्या करने की ज़रूरत है?

उत्तर

4

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

यहाँ कैसे मैं यह कर दिया गया है: मैं एक अलग वर्ग विधानसभा लोड हो रहा है संभाल करने के लिए है, जिसे उपयुक्त नाम दिया AssemblyLoader:

using System; 
using System.IO; 
using System.Linq; 
using System.Reflection; 

internal static class AssemblyLoader 
{ 
    internal static void RegisterAssemblyLoader() 
    { 
     AppDomain currentDomain = AppDomain.CurrentDomain; 
     currentDomain.AssemblyResolve -= OnResolveAssembly; 
     currentDomain.AssemblyResolve += OnResolveAssembly; 
    } 

    private static Assembly OnResolveAssembly(object sender, ResolveEventArgs args) 
    { 
     return LoadAssemblyFromManifest(args.Name); 
    } 

    private static Assembly LoadAssemblyFromManifest(string targetAssemblyName) 
    { 
     Assembly executingAssembly = Assembly.GetExecutingAssembly(); 
     AssemblyName assemblyName = new AssemblyName(targetAssemblyName); 

     string resourceName = DetermineEmbeddedResourceName(assemblyName, executingAssembly); 

     using (Stream stream = executingAssembly.GetManifestResourceStream(resourceName)) 
     { 
      if (stream == null) 
       return null; 

      byte[] assemblyRawBytes = new byte[stream.Length]; 
      stream.Read(assemblyRawBytes, 0, assemblyRawBytes.Length); 


      return Assembly.Load(assemblyRawBytes); 
     } 

    } 

    private static string DetermineEmbeddedResourceName(AssemblyName assemblyName, Assembly executingAssembly) 
    { 
     //This assumes you have the assemblies in a folder named "EmbeddedAssemblies" 
     string resourceName = string.Format("{0}.EmbeddedAssemblies.{1}.dll", 
              executingAssembly.GetName().Name, assemblyName.Name); 

     //This logic finds the assembly manifest name even if it's not an case match for the requested assembly       
     var matchingResource = executingAssembly.GetManifestResourceNames() 
               .FirstOrDefault(res => res.ToLower() == resourceName.ToLower()); 

     if (matchingResource != null) 
     { 
      resourceName = matchingResource; 
     } 
     return resourceName; 
    } 
} 

फिर, मेरे प्लगइन कक्षा में, मैं एक स्थिर निर्माता का उपयोग अपने AssemblyLoader में कॉल करने के लिए । तर्क को अलग वर्ग में ले जाकर, मैं अपने प्लगइन क्लास के स्थिर संदर्भ में संदर्भित प्रकारों की संख्या को सीमित करता हूं, इस प्रकार जोखिम को कम करता हूं जो मैं बाहरी असेंबली में गलती से संदर्भित करता हूं।

using System; 
using Microsoft.Xrm.Sdk; 

public class MyPlugin : IPlugin 
{ 
    static MyPlugin() 
    { 
     AssemblyLoader.RegisterAssemblyLoader(); 
    } 

    public void Execute(IServiceProvider serviceProvider) 
    { 
     //... 
    } 
} 

मैं भी इतना है कि मेरी प्लगइन वर्ग बिल्कुल का उपयोग नहीं करता अन्य वर्गों में काफी सभी बाहरी विधानसभाओं के उपयोगों के लिए ले जाया गया। ज्यादातर, यह सावधानी बरतने से बाहर है।

+0

ठीक है ... आपका समाधान जो मैंने पोस्ट किया है उससे काफी अलग नहीं है ... हालांकि, आपको चेक मार्क मिलता है क्योंकि यह मुझे आश्चर्यचकित करता है कि समस्या तब तक जारी रहेगी जब समस्या की जटिलता कम हो गई और धीरे-धीरे बढ़ी। –

+0

क्या वर्क वर्कफ़्लो के साथ एक ही तकनीक काम करेगी? –

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