2011-11-04 11 views
7

मैं निम्नलिखित कोड का उपयोग करता हूं:मैं किसी अन्य फ़ोल्डर के भीतर से लोड की गई असेंबली से एक प्रकार कैसे प्राप्त कर सकता हूं?

Assembly.LoadFile("the assembly in another folder"); 
var type = Type.GetType("the full name of the type"); 

भले ही असेंबली पहले से ही कोड की इस पंक्ति से पहले लोड हो चुकी थी, यह हमेशा type में शून्य हो जाती है।

पीएस: मैंने नामस्थान, प्रकार का नाम, असेंबली नाम, संस्करण और सार्वजनिक टोकन समेत असेंबली योग्य नाम में पास किया था।

+0

क्या यह विधानसभा भाषा किसी भी तरह से असेंबली भाषा से संबंधित है? –

+0

@ किरिलकिरोव: नहीं। यह नेट में एक प्रकार है। –

+0

@ ऑस्टिन - आह, धन्यवाद :) मुझे टैग द्वारा गुमराह किया गया था। –

उत्तर

9

Type.GetType केवल कॉलिंग असेंबली में प्रकार और mscorlib.dll में प्रकारों की खोज करता है जब तक कि आप प्रकार के असेंबली योग्य नाम को पास न करें। See here.

संपादित

ऐसा लगता है कि Type.GetType केवल लोड संदर्भ में विधानसभाओं से Type उदाहरणों को पुनः प्राप्त करने में सक्षम है। LoadFile का उपयोग करके लोड की गई असेंबली no context में हैं और LoadFrom का उपयोग करके लोड किए गए लोड लोड संदर्भ में हैं; इन संदर्भों में से कोई भी आपको Type.GetType का उपयोग करने की अनुमति देता है ताकि संकल्प विफल हो जाए। This article दिखाता है कि Type जानकारी को Assembly के लिए पुनर्प्राप्त किया जा सकता है जब निर्देशिका में यह एक प्रोबिंग प्राइवेटपैथ के रूप में जोड़ा जाता है क्योंकि यह लोड संदर्भ में समाप्त हो जाएगा लेकिन अन्य संदर्भों में विफल हो जाएगा।

+0

मैंने असेंबली योग्य नाम, नामस्थान, प्रकार का नाम, असेंबली नाम, और संस्करण, सार्वजनिक टोकन समेत पास किया था। – CuiPengFei

+0

@CuiPengFei बस स्पष्ट को खत्म करने के लिए, क्या आप निश्चित हैं कि असेंबली योग्य नाम बिल्कुल केस-सेंसिटिव वैल्यू से मेल खाता है जो आपको मिलेगा यदि आपने असेंबली को स्थगित रूप से संदर्भित किया है और 'टाइपऑफ (टाइपनाम) कहा जाता है .अनुप्रयोग योग्यता नाम'? –

+0

हाँ, मुझे यकीन है। – CuiPengFei

1

आप इस कोशिश कर सकते हैं ....

Assembly.GetAssembly मानता है कि आपके प्रकार का एक उदाहरण है, और Type.GetType मानता है कि आपके पूरी तरह से योग्य प्रकार का नाम है जिन्हें संयोजन के नाम भी शामिल है।

आप रास्ता है कि विधानसभा स्थित है .....

आप केवल आधार प्रकार का नाम है, तो आप इस तरह के और अधिक कुछ करने की जरूरत है दे सकते हैं:

public static String GetAssemblyNameContainingType(String typeName) 
{ 
    foreach (Assembly currentassembly in AppDomain.CurrentDomain.GetAssemblies()) 
    { 
     Type t = currentassembly.GetType(typeName, false, true); 
     if (t != null) {return currentassembly.FullName;} 
    } 

    return "not found"; 
} 

यह भी मान लिया अपने रूट रूट में घोषित किया गया है। आपको नाम में नामस्थान या संलग्न प्रकार प्रदान करना होगा, या उसी तरह पुनरावृत्त करना होगा।

Assembly assem = Assembly.LoadFile("assemblyLocation"); 
assem.GetType("typeName"); 

आप इस विधानसभा के लिए एक संदर्भ रखने पर विचार कर सकते:

+0

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

+0

मैं इसकी अनुशंसा नहीं करता। इसके बजाय, [AppDomain.AssemblyResolve] (http://msdn.microsoft.com/en-us/library/system.appdomain.assemblyload.aspx) ईवेंट से जुड़ें। इस तरह, आप केवल असेंबली को वापस लौटाते हैं, जहां उपर्युक्त कोड में, आप _each और प्रत्येक लोड असेंबली खोजते हैं, साथ ही आप उन लोगों को लोड करना प्रारंभ करते हैं जिन्हें वर्तमान में आवश्यक नहीं है। – Abel

2

यह ऐसा करने का सबसे आसान तरीका है बस इस तरह एक चर में Assembly.LoadFile के रिटर्न मान जाल और GetType फोन उस पर करने के लिए है यदि आप अक्सर उससे प्रकार खींचना चाहते हैं, या जो दूसरों ने सुझाव दिया है और एक अधिक सामान्य विधि बनाते हैं जो सभी भारित असेंबली के माध्यम से लूप करता है।

4

ऐसा करने के लिए "उचित" (एमएस अनुशंसित) तरीका है, जब आपको Type.GetType(string) का उपयोग उन असेंबली में प्रकारों पर करना चाहिए जो लोड संदर्भ में नहीं हैं लेकिन लोड-इन या नो-कॉन्टेक्स्ट संदर्भ में, बाध्य करना है Appdomain.AssemblyResolve घटना। निम्नलिखित कोड अपेक्षाकृत कुशल है:

// this resolver works as long as the assembly is already loaded 
// with LoadFile/LoadFrom or Load(string)/Load(byte[]) 
private static Assembly OnAssemblyResolve(object sender, ResolveEventArgs args) 
{ 
    var asm = (from a in AppDomain.CurrentDomain.GetAssemblies() 
       where a.GetName().FullName == args.Name 
       select a).FirstOrDefault(); 

    if(asm == null) 
     throw FileNotFoundException(args.Name);  // this becomes inner exc 

    return asm; 
} 

// place this somewhere in the beginning of your app: 
AppDomain.CurrentDomain.AssemblyResolve += OnAssemblyResolve; 

यह थोड़ा और अधिक कुशल प्रकट होता है भरी हुई विधानसभाओं का एक शब्दकोश (कुंजी के रूप में विधानसभा के नाम का उपयोग करें) रखने के लिए AssemblyLoad/हल घटनाओं के संयोजन बनाने के लिए।

असेंबली पर।लोडफाइल
इस विधि का उपयोग करने पर कुछ गंभीर दोष हैं। According to MSDN:

LoadFile LoadFrom संदर्भ में फ़ाइलों को लोड नहीं करता, और लोड पथ का उपयोग निर्भरता हल नहीं होती है, के रूप में LoadFrom विधि है।

तो, यदि संभव हो, तो लोडफ़ाइल का उपयोग न करें। परिणामस्वरूप असेंबली को संदर्भ संदर्भ में लोड किया गया है, जिसमें लोड-से संदर्भ के मुकाबले और भी कमियां हैं। इसके बजाय, Assembly.LoadFrom का उपयोग करें और निर्भरता लोड पथ से स्वचालित रूप से लोड हो जाएगी।

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

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