2013-01-03 31 views
5

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

चूंकि मेरे पास प्लग-इन होने वाले कोड पर कोई नियंत्रण नहीं है, इसलिए मैं सही वर्ग से (विशिष्ट इंटरफ़ेस से) 1 विशिष्ट विधि (इंटरफ़ेस से) चलाने में सक्षम होना चाहता हूं (जब तक मैं इंटरफेस्ड क्लास नहीं ढूंढता)।

के बाद से किसी को भी अच्छा निर्माता कोड कि Activator.CreateInstance पर निष्पादित बना सकते हैं, मैं FormatterServices.GetUninitializedObject का उपयोग करके हल कर सकते हैं कि। लेकिन कक्षा में खेतों पर कोड शुरू होने पर यह मदद नहीं करता है।

public class myclass : myinterface { 

    public someotherclass name = new someotherclass() 

    public myclass() { 
    //Unknown code 
    } 

    //I only want this run. 
    public string MyProperty{ 
    get { 
     return "ANiceConstString"; 
    } 
    } 
} 

दोनों तरीकों (CreateInstance/GetUninitializedObject) के साथ समस्या यह है कि के someotherclass चलाया जाएगा निर्माता।

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

तो इस प्रश्न से चिपके रहें: क्या .NET 100% गैर-प्रारंभिक कक्षा बनाने के लिए किसी भी तरह का समर्थन करता है?

उत्तर के लिए अद्यतन करें। मैंने अपना प्रश्न पोस्ट करने से पहले इसका परीक्षण किया।

उत्तर के लिए कि कुछ अन्यथा दौड़ नहीं पाएंगे, मैंने पहले से ही इसका परीक्षण किया है और यह स्थिर होने पर चलाया जाता है।

public class myclass : myinterface { 

    static Tutle test; 

    public myclass() { 
     test = new Tutle(); 
    } 

    public class Tutle { 
     public Tutle() { 
      MessageBox.Show("RUN!"); 
     } 
    } 
} 

CreateInstance संदेशबॉक्स दिखाता है। GetUninitializedObject नहीं करता है।

public class myclass : myinterface { 

    static Tutle test = new Tutle(); 

    public myclass() { 
    } 

    public class Tutle { 
     public Tutle() { 
      MessageBox.Show("RUN!"); 
     } 
    } 
} 

CreateInstance संदेशबॉक्स दिखाता है। GetUninitializedObject संदेशबॉक्स दिखाता है।

क्या स्थिर क्षेत्र intializers और ctors के आसपास पाने का कोई तरीका है?

+0

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

+2

जब भी आपके पास निष्पादित कोड का कोई नियंत्रण नहीं होता है, तो आप उस कोड को सीमित अनुमतियों के साथ एक अलग AppDomain में निष्पादित करने पर विचार कर सकते हैं। यह एक अनियमित वस्तु बनाने का विकल्प हो सकता है। –

उत्तर

14
सीधे शब्दों में

: निर्माता/क्षेत्र initializers नहीं चलेंगे

var obj = (myclass)FormatterServices.GetUninitializedObject(typeof(myclass)); 

है। बिलकुल। यह someotherclass के लिए निर्माता चलाएगा; namenull होगा।

हालांकि, यह किसी भी स्थिर कन्स्ट्रक्टर निष्पादित करेगा, जो मानक .NET नियमों के तहत आवश्यक हो।

हाउवर! मुझे ध्यान रखना चाहिए कि यह विधि विज्ञापन-प्रसार के उपयोग के लिए नहीं है; इसका प्राथमिक उद्देश्य धारावाहिकों और रिमोटिंग इंजनों में उपयोग के लिए है। एक बहुत अच्छा मौका है कि इस तरह से बनाए गए प्रकार सही तरीके से काम नहीं करेंगे, अगर आपने उन्हें बाद में वैध स्थिति में रखने के लिए कदम नहीं उठाए हैं (जो कोई भी धारावाहिक/रिमोटिंग इंजन करना सुनिश्चित करेगा)।

+1

सही, फील्ड प्रारंभकर्ता ('सार्वजनिक someotherclass नाम = नया someotherclass(); 'आपके उदाहरण में) * निष्पादित नहीं किया जाएगा। –

+0

मेरे अपडेट की जांच करें। GetUninitializedObject कोड चलाता है ... पोस्ट करने से पहले ही परीक्षण किया गया है। समुद्री मील दूर। स्टेटिक मुद्दा था। तो फिर स्थिर होने के लिए कोई रास्ता नहीं है? – Wolf5

+1

@ वुल्फ 5 मैंने भी परीक्षण किया; पी और नहीं: यह नहीं है (संपादित करें: यह टिप्पणी अब पुरानी है क्योंकि अब इसे 'स्थिर 'चिह्नित किया गया है) –

5

एक वैकल्पिक डिजाइन विचार के रूप में:

[SomeFeature("ANiceConstString")] 
public class myclass : myinterface { 

    public someotherclass name = new someotherclass() 

    public myclass() { 
    //Unknown code 
    } 
} 

अब आप इन्स्टेन्शियशन बिना सुविधा का उपयोग कर सकते; बस का उपयोग करें:

var attrib = (SomeFeatureAttribute)Attribute.GetCustomAttribute(
    type, typeof(SomeFeatureAttribute)); 
string whatever = attrib == null ? null : attrib.Name; 

साथ:

[AttributeUsage(
    AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum)] 
public sealed class SomeFeatureAttribute : Attribute 
{ 
    private readonly string name; 
    public string Name { get { return name; } } 
    public SomeFeatureAttribute(string name) { this.name = name; } 
} 
+0

धन्यवाद। मुझे लगता है कि मैं इसे जोड़ दूंगा। चूंकि इंटरफ़ेस प्रकाशित और सेट किया गया है, यदि विशेषता सेट की गई है, तो मैं एक प्रीकेक कर सकता हूं, और उदाहरण बनाने से पहले इसका उपयोग कर सकता हूं। अनिच्छुक अनुकूलता। – Wolf5

+0

मुझे यह बहुत बेहतर पसंद है। 'GetUninitializedObject' बहुत खतरनाक लगता है! –