2009-05-24 28 views
5

मैं कुछ सी # वर्ग लिब्री लिखता हूं और मैं अपने वर्गों के लिए निर्भरता इंजेक्शन प्रदान करने के लिए निनजेक्ट का उपयोग करना चाहता हूं। क्या क्लास लिबररी के लिए कुछ कोड (विधि) घोषित करना संभव है जो क्लास लिबररी लोड होने वाली प्रत्येक फीम को निष्पादित किया जाएगा। मुझे निनजेक्ट के लिए बाइंडिंग को परिभाषित करने की आवश्यकता है।सी # विधि जिसे असेंबली के बाद निष्पादित किया गया है

उत्तर

1

मैंने पिछले 9 महीनों में निनजेक्ट का काफी उपयोग किया है। ऐसा लगता है कि आपको क्या करना है, बाइंडिंग को पंजीकृत करने के लिए निनजेक्ट कर्नेल में आपके पुस्तकालय में मौजूद आपके मॉड्यूल को "लोड" करना है।

मुझे यकीन नहीं है कि आप निंजा 1.x या 2.0 बीटा का उपयोग कर रहे हैं। दोनों संस्करण चीजों को थोड़ा अलग तरीके से करते हैं, हालांकि अवधारणात्मक रूप से, वे वही हैं। मैं इस चर्चा के लिए संस्करण 1.x के साथ रहूंगा। जानकारी का दूसरा भाग मुझे नहीं पता है कि आपका मुख्य कार्यक्रम निनजेक कर्नेल को तुरंत चालू कर रहा है और आपकी लाइब्रेरी बस उस कर्नेल को बाइंडिंग जोड़ रही है, या यदि आपकी लाइब्रेरी में कर्नेल और बाइंडिंग हैं। मुझे लगता है कि आपको मुख्य पुस्तकालय में मौजूदा निंजा कर्नेल में अपनी लाइब्रेरी में बाइंडिंग जोड़ने की आवश्यकता है। अंत में, मैं यह धारणा दूंगा कि आप इस पुस्तकालय को गतिशील रूप से लोड कर रहे हैं और यह मुख्य कार्यक्रम से स्थिर रूप से जुड़ा हुआ नहीं है।

पहली बात यह है कि अपनी लाइब्रेरी में एक निंजा मॉड्यूल परिभाषित करें जिसमें आप अपनी सभी बाइंडिंग पंजीकृत करते हैं - आप पहले ही ऐसा कर चुके हैं, लेकिन यह उल्लेखनीय है।उदाहरण के लिए:

public class MyLibraryModule : StandardModule { 
    public override void Load() { 
    Bind<IMyService>() 
     .To<ServiceImpl>(); 
    // ... more bindings ... 
    } 
} 

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

// Somewhere, you define the kernel... 
var kernel = new StandardKernel(); 

// ... then elsewhere, load your library and load the modules in it ... 

var myLib = Assembly.Load("MyLibrary"); 
var stdModuleTypes = myLib 
         .GetExportedTypes() 
         .Where(t => typeof(StandardModule).IsAssignableFrom(t)); 


foreach (Type type in stdModuleTypes) { 
    kernel.Load((StandardModule)Activator.CreateInstance(type)); 
} 

एक बात, आप कई पुस्तकालयों लोड और कई प्रकार के रजिस्टर करने के लिए आगे उपरोक्त कोड सामान्यीकरण कर सकते हैं। साथ ही, जैसा कि मैंने ऊपर बताया है, निनजे 2 में इस तरह की क्षमता अंतर्निहित है - इसमें वास्तव में निर्देशिका स्कैन करने, असेंबली लोड करने और मॉड्यूल पंजीकृत करने की क्षमता है। बहुत ही शांत।

यदि आपका परिदृश्य जो मैंने रेखांकित किया है उससे थोड़ा अलग है, तो इसी तरह के सिद्धांतों को अनुकूलित किया जा सकता है।

6

ऐसा लगता है कि आप C++ के DllMain के बराबर की तलाश में हैं। सी # में ऐसा करने का कोई तरीका नहीं है।

क्या आप हमें अपने परिदृश्य के बारे में कुछ और जानकारी दे सकते हैं और आपको डेलमेन शैली समारोह में निष्पादित करने के लिए कोड की आवश्यकता क्यों है?

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

-1

जहाँ तक मुझे पता है कि उत्तर नहीं है। जैसा कि मैं समझता हूं कि आप अपनी कक्षा पुस्तकालय में अपने आईओसी कंटेनर को कॉन्फ़िगर करना चाहते हैं और यदि ऐसा है तो ऐसा करने का अच्छा विचार नहीं है। अगर आप अपने बाइंडिंग को परिभाषित करते हैं कक्षा पुस्तकालय तो निर्भरता इंजेक्शन का उपयोग क्या है? हम निर्भरता इंजेक्शन का उपयोग करते हैं ताकि हम रनटाइम पर निर्भरता इंजेक्ट कर सकें, फिर हम विभिन्न परिदृश्यों में विभिन्न वस्तुओं को इंजेक्ट कर सकते हैं। हालांकि आईओसी कंटेनर को कॉन्फ़िगर करने के लिए सबसे अच्छी जगह आपके एप्लिकेशन की शुरुआत है (चूंकि एक आईओसी कंटेनर एप्लिकेशन के लिए रीढ़ की हड्डी की तरह है :)) लेकिन इसे बूटस्ट्रैप पर रखा जाना चाहिए जो एप्लिकेशन को शुरू करने के लिए ज़िम्मेदार है। सरल अनुप्रयोगों में यह मुख्य विधि हो सकती है।

+0

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

0

क्या आप ग्राहक कोड को नियंत्रित कर सकते हैं? यदि हां, असेंबली लोड करते समय जादू करने की कोशिश करने के बजाय, मैं रजिस्ट्री जैसे एकल वर्ग को लागू करने के लिए जाऊंगा जो बाइंडिंग करता है, एक इंटरफेस आईआरजीस्ट्री लागू करता है। फिर लोडिंग के दौरान आप अपनी असेंबली में अग्निशामक के कार्यान्वयन और आवश्यक विधियों को आग लग सकते हैं।

आप भी अपनी कक्षाओं पर गुण कर सकते हैं: इन विशेषताओं के लिए

[Component(Implements=typeof(IMyDependency)] 

देखो और उन्हें क्लाइंट की तरफ कंटेनर के लिए लोड।

या आप MEF पर एक नज़र डाल सकते हैं जो इस तरह की स्थितियों के लिए एक पुस्तकालय है।

1

क्या आपने AppDomain.AssemblyLoad ईवेंट की कोशिश की है? एक असेंबली लोड होने के बाद यह आग लगती है।

AppDomain.CurrentDomain.AssemblyLoad += (s, e) => 
{ 
    Assembly justLoaded = e.LoadedAssembly; 
    // ... etc. 
}; 
संबंधित मुद्दे

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