2010-12-14 12 views
10

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

मुझे प्रत्येक डीएलएल के भीतर कुछ प्रकारों तक पहुंचने की आवश्यकता है, लेकिन इन प्रकारों का एक ही पूर्णतः योग्य नाम है। > SomeProduct.Type1 DLL 2 है companyDLL.dll - - तो कहते हैं कि DLL1 है companyDLL.dll की सुविधा देता है> someProduct.Type1

मैं एक ही परियोजना के भीतर दोनों 'टाइप 1' कैसे उपयोग कर सकते हैं?

मैंने पहले ही 'बाहरी उपनाम' का उपयोग करने का प्रयास किया है, लेकिन इसके लिए मुझे एक डीएलएल का नाम बदलने की आवश्यकता है।

कृपया मुझे बताएं कि मेरे प्रश्न के लिए और स्पष्टीकरण की आवश्यकता है या नहीं।

+8

यह वर्ग की श्रेणी में आता है "यदि आप ऐसा करने की कोशिश कर रहे हैं, तो आपका डिज़ाइन गंभीर रूप से टूटा हुआ है।" – cdhowie

+0

निश्चित रूप से सहमत है, यह एक ऐसे उपकरण के लिए है जिसके लिए कंपनी उत्पाद के दो संस्करणों (.NET के साथ बनाया गया) से जानकारी की आवश्यकता है। लेकिन यहां सवाल में उत्पाद विनियमित है और इसलिए बदला नहीं जा सकता है। – varosh

उत्तर

0

मैं इसे संभालने के दो तरीकों के बारे में सोच सकता हूं।

  1. प्रत्येक डीएलएल को एक अलग ऐपडोमेन में लोड करें। विभिन्न गुणों और विधियों को गुदगुदी करने के लिए आपको ऐपडोमेन सीमा पर कॉल करना होगा।

  2. असेंबली लोड करने से पहले, अलग-अलग इकट्ठा करने और फिर प्रत्येक असेंबली को फिर से इकट्ठा करने और उन्हें अद्वितीय (शायद गतिशील रूप से जेनरेट किए गए) नामस्थान में डाल दें। ऐसे उपकरण हैं जो इस (1) (2) में सहायता कर सकते हैं। आप संभावित रूप से इसे स्वचालित कर सकते हैं।

लेकिन मेरी मूल भावना यह है कि आपको वास्तव में ऐसा नहीं करना चाहिए। इस समस्या को अपस्ट्रीम को हल करना आसान है, इससे पहले कि आप पहले ही संकलित असेंबली के बाद इसे हल कर सकें।

+0

सेसिल एक हल्कापन से बेहतर दृष्टिकोण हो सकता है, क्योंकि आप सीधे आई # का उपयोग करके आईएल में हेरफेर कर सकते हैं। – cdhowie

+0

उपरोक्त # 1 के लिए: मैं एक ही प्रोजेक्ट में उसी नाम के साथ दो डीएलएल का संदर्भ कैसे जोड़ सकता हूं? – varosh

3

विभिन्न नामस्थानों के साथ असेंबली लाने के लिए extern alias का उपयोग करना। यदि आप नामस्थान को अलग कर सकते हैं, तो आप प्रकार के लिए स्थानीय उपनाम बनाने के लिए using altType1 = someProduct.Type1 का उपयोग करने में सक्षम होना चाहिए।

पहले कमांड लाइन से विधानसभाओं अर्हता:

/r:ProductA=companyDLLA.dll 
/r:ProductB=companyDLLB.dll 

फिर extern alias का उपयोग कर उन्हें संदर्भ:

extern alias productA; 
extern alias productB; 

अंत में आप स्थानीय प्रकार उर्फ ​​कर सकते हैं:

using productTypeA = productA.Type1; 
using productTypeB = productB.Type1; 
+0

दुर्भाग्य से मेरे लिए, दो डीएलएस का एक ही नाम है। I.e./r:ProductA=companyDLLA.dll /r:ProductB=companyDLLA.dll – varosh

+0

क्या कोई कारण है कि आप DLL का नाम नहीं बदल सकते हैं? अगर मैं आपकी स्थिति में था, तो मैं उन्हें 'companyDLLv1.dll' और companyDLLv2.dll' नाम बदलने का प्रयास करूंगा। –

+0

हां, डीएलएल का नाम बदला नहीं जा सकता है। यहां प्रश्न में डीएलएल विनियमित हैं और आधिकारिक अनुमोदन प्रक्रिया (जो मेरे परिदृश्य के लिए सवाल से बाहर है) के बिना नहीं बदला जा सकता है – varosh

11

यदि आपका दो डीएलएल का एक ही नाम है, आपको उनका नाम बदलना होगा। जैसे Assembly1.dll और Assembly 2.dll।

इन डीएलएल को अपनी परियोजना में एक संदर्भ के रूप में जोड़ें जैसा कि आप सामान्य रूप से करेंगे और प्रत्येक संदर्भ के गुणों में उपनाम निर्दिष्ट करते हैं।

DLL का उपयोग करते समय अपने कोड में extern alias का उपयोग करने के लिए निर्दिष्ट करें कि आप किस संदर्भ का संदर्भ देना चाहते हैं।

extern alias Assembly1Reference; 
using Assembly1Reference::AssemblyNamespace.MyClass; 

आप इसे इस तरह छोड़ देते हैं तो आप सबसे अधिक संभावना एक FileNotFoundException कह रही है कि यह फ़ाइल या विधानसभा लोड नहीं कर सका मिल जाएगा। इसे ठीक करने के लिए आपको ResolveEventHandler जोड़ने की आवश्यकता है जो उस सही असेंबली को लोड करेगा जिसे आप उपयोग करने का प्रयास कर रहे हैं। ऐसा करने के लिए आपको यह निर्दिष्ट करना होगा कि आप अपनी डीएलएल फाइलों को कहां संग्रहीत कर रहे हैं।नीचे दिए गए मामले में, मैंने डीएलएल फ़ाइलों को मैन्युअल रूप से प्रोजेक्ट डीबग फ़ोल्डर में कॉपी किया है। जहां यह कहता है "असेंबली का नाम 1" आप डीएलएल का संदर्भ देने के बाद नाम ढूंढ सकते हैं, प्रोजेक्ट बना सकते हैं, और नोटपैड के साथ csproj फ़ाइल खोल सकते हैं। मेरे उदाहरण कोड के नीचे क्या देखना है।

extern alias Assembly1Reference; 
extern alias Assembly2Reference; 

static void Load() 
{ 
    AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve; 
    Do(); 
} 

static void Do() 
{ 
    new Assembly1Reference.Assembly.Class(); 
    new Assembly2Reference.Assembly.Class(); 
} 

static System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) 
{ 
    string currentPath = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location); 
    if(args.Name == "Name of assembly1")//Found in csproj file after referenced and built 
    { 
     return System.Reflection.Assembly.LoadFile(System.IO.Path.Combine(currentPath, "Assembly1.dll")); 
    } 
    if(args.Name == "Name of assembly2")//Found in csproj file after referenced and built 
    { 
     return System.Reflection.Assembly.LoadFile(System.IO.Path.Combine(currentPath, "Assembly2.dll")); 
    } 
    return null; 
} 

जैसा कि वादा किया गया है, यहां एक संदर्भ है जो csproj फ़ाइल में दिखता है। नाम विशेषता के अंदर सबकुछ है।

<Reference Include="MyAssembly_3.6.2.0, Version=3.6.2.0, Culture=neutral, PublicKeyToken=12341234asdafs43, processorArchitecture=MSIL"> 
     <SpecificVersion>False</SpecificVersion> 
     <HintPath>Resources\Assembly1.dll</HintPath> 
     <Aliases>Assembly1Reference</Aliases> 
</Reference> 

मैं जानता हूँ कि यह देर हो चुकी है, लेकिन उम्मीद है कि यह अब से इस पृष्ठ पर आने वाले किसी को भी मदद मिलेगी।

+0

यह उपयोगी है और मैं इसे आंशिक रूप से काम कर सकता हूं लेकिन मेरे पास निम्नलिखित प्रश्न हैं। इसका उद्देश्य क्या है? 'स्थिर शून्य करें() {नई असेंबली 1Reference.Assembly.Class(); नई असेंबली 2Reference.Assembly.Class(); } 'App.config के माध्यम से कोड के माध्यम से असेंबली को हल करने का लाभ भी है [https://] [https://stackoverflow.com/a/3163050/431561)। मेरे मामले में, हमेशा असेंबली का नवीनतम संस्करण लोड हो रहा है। विशेष नामित असेंबली के सटीक डीएलएल को लोड करने के लिए मुझे क्या करना चाहिए। – Rajaraman

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