2012-05-24 10 views
8

मैं एक उदाहरण है:क्या मैं एक इंटरफ़ेस के साथ एक्टिवेटर। क्रिएट इंस्टेंस का उपयोग कर सकता हूं?

 Assembly asm = Assembly.Load("ClassLibrary1"); 
     Type ob = asm.GetType("ClassLibrary1.UserControl1"); 
     UserControl uc = (UserControl)Activator.CreateInstance(ob); 
     grd.Children.Add(uc); 

वहाँ मैं एक वर्ग का उदाहरण बनाकर हूँ, लेकिन मैं एक वर्ग है जो किसी इंटरफ़ेस लागू करता है का एक उदाहरण है कि कैसे बना सकते हैं? यानी उपयोगकर्ता नियंत्रण 1 लागू आईएलओड इंटरफ़ेस।

यू: मैं ऑब्जेक्ट को बाद में इंटरफ़ेस में डाल सकता हूं, लेकिन मुझे नहीं पता कि असेंबली में किस प्रकार का इंटरफ़ेस लागू होता है।

+6

आप एक इंटरफेस का एक उदाहरण नहीं बना सकते; आप इंटरफ़ेस को लागू करने वाले वर्ग को बना सकते हैं और इसे इंटरफ़ेस के रूप में पास कर सकते हैं। – Marco

+1

आप आईएलओड के किसी ऑब्जेक्ट को तुरंत चालू नहीं कर सकते हैं, यह एक इंटरफ़ेस है। – JustinDanielson

उत्तर

14

यह कुछ कोड है जिसे मैंने कुछ बार उपयोग किया है।

Type[] iLoadTypes = (from t in Assembly.Load("ClassLibrary1").GetExportedTypes() 
        where !t.IsInterface && !t.IsAbstract 
        where typeof(ILoad).IsAssignableFrom(t) 
        select t).ToArray(); 

तो फिर तुम ClassLibrary1 में सभी प्रकार कि ILoad लागू है: यह एक सभा में सभी प्रकार है कि एक निश्चित इंटरफ़ेस को लागू पाता है।

फिर आप उन सभी को दृष्टांत सकता है:

ILoad[] instantiatedTypes = 
    iLoadTypes.Select(t => (ILoad)Activator.CreateInstance(t)).ToArray(); 
+0

धन्यवाद, अच्छा समाधान। –

+0

मुझे निम्न त्रुटि मिल रही है: 'स्रोत प्रकार' System.Reflection.Assembly 'के लिए क्वेरी पैटर्न का कार्यान्वयन नहीं मिला। 'कहां नहीं मिला'। – dotNET

+1

इसे मिला। उपर्युक्त कोड में 'लोड ("क्लास लाइब्रेरी 1")' का पालन किया जाना चाहिए। .GetExportedTypes(); '। – dotNET

4

आप एक इंटरफेस का उदाहरण नहीं बना सकते हैं, लेकिन अगर

UserControl1 implements ILoad inteface

आप के रूप में ILoad

ILoad uc = (ILoad)Activator.CreateInstance(ob); 
grd.Children.Add(uc); 

जिसके परिणामस्वरूप वस्तु का उपयोग कर सकते इसके अलावा, आप, यदि आप लिखना इंटरफ़ेस के जरिए इलाज की जरूरत नहीं है

UserControl1 uc = (UserControl1)Activator.CreateInstance(ob); 
grd.Children.Add(uc); 

ILoad के सदस्य कॉल uc.SomeILoadMethod();

+0

प्रदान किया गया 'ओबी' अभी भी एक वर्ग का प्रतिनिधित्व करने वाला एक प्रकार है, न कि इंटरफ़ेस। – Guillaume

+0

@ गुइलाइम निर्मित ऑब्जेक्ट इलोड लागू करता है, इसलिए इसे सीधे – archil

+0

का उपयोग किया जा सकता है, लेकिन मैं असेंबली में टाइप कैसे ढूंढ सकता हूं, जो ** ILoad ** लागू करता है? –

3

इंटरफेस एक इंटरफ़ेस है। यह एक टेम्पलेट है। आप एक इंटरफ़ेस को तुरंत चालू क्यों करना चाहते हैं? इंटरफ़ेस को कार्यान्वित करें और उस वर्ग को तुरंत चालू करें। आप एक इंटरफ़ेस को तुरंत चालू नहीं कर सकते हैं, यह वास्तव में समझ में नहीं आता है।

+1

बेशक यह एक इंटरफ़ेस को तुरंत चालू करने का एक आसान तरीका समझ में आता है। डीटीओ की कल्पना करो। बिना व्यवहार के पीओसीओ। आप उन्हें नकली ढांचे में आसानी से उपयोग करने के लिए इंटरफ़ेस के रूप में बनाना चाहते हैं, लेकिन जब आप इंटरफ़ेस को कार्यान्वित करते हैं, तो आप मूल रूप से कोड के दो समान टुकड़ों के साथ समाप्त होते हैं जिन्हें आपको बनाए रखने की आवश्यकता होती है। यही कारण है कि कुछ ढांचे, जैसे NServiceBus, आपको "इंटरफेस को तत्काल" करने देता है। मैं यह नहीं कह रहा हूं कि इसे एक्टिवेटर जैसी सुविधाओं में आसानी से किया जा सकता है, मैं बस इतना कह रहा हूं कि आप इसे "इसे समझ में नहीं आता" के रूप में इसे उड़ा नहीं सकते हैं – Morten

4

जो आप चाहते हैं वह आईओसी कंटेनर जैसे 'एन इंजेक्ट' का उपयोग करके हासिल किया जा सकता है। जब आप इंटरफ़ेस का अनुरोध करते हैं तो आप एक ठोस प्रकार को वापस करने के लिए एक कंटेनर कॉन्फ़िगर कर सकते हैं।

2

पुस्तकालय परियोजना में संदर्भित किया गया था, तो आप उपयोग कर सकते हैं:

static public IEnumerable<Type> GetTypesFromLibrary<T>(String library) 
    { 
     var MyAsemblies = AppDomain.CurrentDomain.GetAssemblies() 
         .Where(a=>a.GetName().Name.Equals(library)) 
         .Select(a=>a); 
     var Exported = MyAsemblies 
         .FirstOrDefault() 
         .GetExportedTypes(); 
     var Asignable = Exported 
         .Where (t=> !t.IsInterface && !t.IsAbstract 
         && typeof(T).IsAssignableFrom(t)) 
         .Select(t=>t) 
         .AsEnumerable(); 
     return Asignable; 
    } 

    static public T GetInstanceOf<T>(String library, String FullClassName) 
    { 
     Type Type = GetTypesFromLibrary<T>(library) 
         .Where(t => t.FullName.Equals(FullClassName)) 
         .FirstOrDefault(); 
     if (Type != null) 
     { 
      T Instance = (T)Activator.CreateInstance(Type); 
      return Instance; 
     } 
     return default(T); 
    } 
2

स्वीकार किए जाते हैं जवाब के साथ केवल एक समस्या यह है कि आप होना आवश्यक है कि इंटरफेस लागू करने वाली आपकी असेंबली पर एक ठोस वर्ग।

इससे बचने के लिए मैंने अपना कस्टम एक्टिवेटर बनाया है जो रनटाइम पर गतिशील ऑब्जेक्ट बनाने में सक्षम है और इसे वांछित इंटरफ़ेस लागू करता है। https://github.com/fabriciorissetto/CustomActivator

कॉल सरल है::

मैं GitHub पर डाल दिया

CustomActivator.CreateInstance<MyInterface>(); 
संबंधित मुद्दे

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