2010-07-28 16 views
17

में कुछ मूल प्रकार के सभी वर्गों को प्राप्त करने के प्रतिबिंब का उपयोग करना मेरे पास एक डीएल है जिसमें कई वर्ग शामिल हैं जो सभी को कमांडबेस क्लास से प्राप्त होता है। मैं सी # में प्रतिबिंब का उपयोग करके इन सभी वर्गों (कमांडए, कमांडबी, कमांडसी, आदि ...) के उदाहरण प्राप्त करने की कोशिश कर रहा हूं ताकि मैं प्रत्येक पर एक विशिष्ट विधि को कॉल कर सकूं। यहां मेरे पास अब तक है:डीएल

//get assemblies in directory. 
string folder = Path.Combine(HttpContext.Current.Server.MapPath("~/"), "bin"); 
var files = Directory.GetFiles(folder, "*.dll"); 
//load each assembly. 
foreach (string file in files) 
{ 
    var assembly = Assembly.LoadFile(file); 
    if (assembly.FullName == "MyCommandProject") 
    { 
    foreach (var type in assembly.GetTypes()) 
    { 
     if (!type.IsClass || type.IsNotPublic) continue; 
     if(type is CommandBase) 
     { 
     var command = Activator.CreateInstance(type) as CommandBase; 
     } 
    } 
    } 
} 

मुझे 2 समस्याएं हैं। पहला मुद्दा यह है कि "अगर (प्रकार कमांडबेस है") निम्नलिखित चेतावनी देता है:

दी गई अभिव्यक्ति कभी भी उपलब्ध कमांडबेस का नहीं है।

दूसरा मुद्दा यह है कि मैं यह नहीं समझ सकता कि वास्तविक वस्तु (कमांडए, कमांडबी, आदि ...) का उदाहरण कैसे प्राप्त करें, बस इसे कमांडबेस में परिवर्तित करना पर्याप्त नहीं है।

+0

आपकी आखिरी पंक्ति ठीक से उदाहरण नहीं बनाती है? 'एक्टिवेटर के साथ। क्रिएटइंस्टेंस() ', आपके पास कमांडए, कमांडबी ... वर्ग (' टाइप' के आधार पर) का उदाहरण होना चाहिए, नहीं? –

+0

सक्रियण। क्रिएट इंस्टेंस() प्रकार ऑब्जेक्ट देता है। – Justin

+0

हां लेकिन यह आपके द्वारा प्रदान किए गए प्रकार का एक वस्तु देता है। आप इसे "ऑब्जेक्ट" var या "कमांडबेस" var में संग्रहीत कर सकते हैं, यह अभी भी कमांडए, कमांडबी, आदि उदाहरण होगा। आप इसे बाद में अपने "वास्तविक" प्रकार में डाल सकते हैं। मेरे पास जांच करने के लिए एक विजुअल स्टूडियो नहीं है लेकिन मुझे नहीं पता कि समस्या क्या है। –

उत्तर

29

यह वह तरीका है जिसका उपयोग मैं इंटरफ़ेस के आधार पर लोड करने के लिए करता हूं।

private static List<T> GetInstances<T>() 
{ 
     return (from t in Assembly.GetExecutingAssembly().GetTypes() 
       where t.GetInterfaces().Contains(typeof (T)) && t.GetConstructor(Type.EmptyTypes) != null 
       select (T) Activator.CreateInstance(t)).ToList(); 
} 

और यहां वही कार्य है जो बेस क्लास के आधार पर वापस खींचता है।

private static IList<T> GetInstances<T>() 
{ 
     return (from t in Assembly.GetExecutingAssembly().GetTypes() 
         where t.BaseType == (typeof(T)) && t.GetConstructor(Type.EmptyTypes) != null 
         select (T)Activator.CreateInstance(t)).ToList(); 
} 

बेशक इसे आपके द्वारा लोड किए जा रहे संदर्भ पर थोड़ा सा संशोधित करने की आवश्यकता होगी।

+0

धन्यवाद, लेकिन किसी कारण से यह केवल कमांडबेस क्लास देता है, न कि कक्षाएं जो इसके उत्तराधिकारी हैं। इसके अलावा, अगर मैं इसे "GetInstances ()" कहता हूं, तो यह मुझे कमांडबेस ऑब्जेक्ट्स की एक सूची देता है, न कि मुझे आवश्यक वस्तुओं - कमांडए, कमांडब, आदि .. ऐसा लगता है कि मुझे काम करने के लिए इंटरफ़ेस का उपयोग करने की आवश्यकता है । – Justin

+0

आपके कमांडबेस क्लास के लिए उपयोग करने के लिए आपके लिए एक दूसरा फ़ंक्शन जोड़ा गया है। आपको कमांडबेस से प्राप्त कक्षाओं के उदाहरण की एक सूची पुनर्प्राप्त करनी चाहिए। काम करता है जब मैं इसे एक साधारण स्निपेट परीक्षण में फेंक देता हूं। –

+0

मैंने इंटरफेस का उपयोग करने के लिए स्विचिंग समाप्त कर दी और अपना पहला कोड उदाहरण इस्तेमाल किया, धन्यवाद! – Justin

2

ऐसा इसलिए है क्योंकि आपका type वैरिएबल Type है, CommandBase नहीं है।

आप

+1

वह नहीं होगा अगर (टाइप == टाइपफ (कमांडबेस)) '? – Greg

+1

यह व्युत्पन्न कक्षाओं के लिए काम नहीं करेगा। –

+1

यह "है" के बजाय "==" होने पर समाप्त हुआ लेकिन हाँ, जिसने काम किया, धन्यवाद। मेरे दूसरे मुद्दे पर कोई सलाह? – Justin

7

बदलें type is CommandBasetypeof(CommandBase).IsAssignableFrom(type)

+0

+1 आपको यह सही मिला –

+0

+1 जब मैं टाइप कर रहा था, तो मैंने आपका परिणाम नहीं देखा, हालांकि यह एमएसडीएन कहता है, "यदि IsSubclassOf IsAssignableFrom के विपरीत है। यानी, अगर t1.IsSubclassOf (t2) सत्य है, तो t2। IsAssignableFrom (टी 1) भी सच है। " इसलिए हम दोनों समान रूप से सही हैं, मैं उत्तर और == उत्तरों के उत्तर की ओर इशारा कर रहा था। –

6

करने के लिए (सुधार के लिए धन्यवाद ग्रेग)

if(type == typeof(CommandBase)) 

चाहते हैं तो आप को बदलना होगा

if(type is CommandBase) 

को

if(type.IsSubclassOf(typeof(CommandBase))) 

यदि IsSubclassOf IsAssignableFrom के विपरीत है। यही है, अगर t1.IsSubclassOf (t2) सत्य है, तो t2.IsAssignableFrom (t1) भी सत्य है।

+0

यही है, मेरे उत्तर को छोड़कर, जो शुरुआत से सही था। :), लेकिन मैं आपको सही होने के लिए एक +1 दे रहा हूं और क्योंकि मैंने कभी भी IsSubclassOf विधि को कभी नहीं देखा है, क्योंकि मैं केवल IsAssignableFrom का उपयोग करता हूं। –