2012-09-07 12 views
7

के अंदर निर्भरता इंजेक्शन मैं एक्सेल VSTO प्रोजेक्ट के लिए DI को कॉन्फ़िगर करने का प्रयास कर रहा हूं।एक्सेल VSTO और Ninject.Extensions.Factory

किसी दिए गए वर्कशीट के लिए जेनरेट कोड-बैक मुझे स्टार्टअप नामक एक ईवेंट प्रदान करता है, जो स्टार्टअप, चेंज, पहले डबलक्लिक और इसी तरह की घटनाओं के लिए ईवेंट हैंडलर सेट करने के लिए प्रतिलिपि है।

मुझे लगता है कि आमतौर पर एक अच्छी प्रैक्टिस कोड-बैक फाइलों में कोड से बचने के लिए होती है।
मैं जो करता हूं वह बाहरी कक्षाएं बनाता है जो वर्कशीट में हेरफेर करने और वेब सेवाओं, डेटाबेस और डोमेन तर्क जैसे बाहरी कोड को कॉल करने के लिए ज़िम्मेदार हैं।

मैं कोडबेहिंड फ़ाइल द्वारा उपभोग करने के लिए सफलतापूर्वक एक फैक्ट्री बना सकता हूं और वर्कशीट लॉजिक क्लास को तुरंत चालू कर सकता हूं।

उदाहरण के लिए:

//...inside Sheet1.cs 

private IExpenseWorksheetFactory _factory; 

void ExpensesBeforeRightClick(Excel.Range target, ref bool cancel) 
{ 
    Application.EnableEvents = false; 

    var popup = _factory.CreateContextMenu(); 
    popup.ShowContextMenu(target, ref cancel); 

    Application.EnableEvents = true; 
} 
// ... rest of Sheet1.cs 

कोड ऊपर के अंदर है कोड-पीछे दृश्य स्टूडियो उत्पन्न फ़ाइल और यह कम से कम है। पॉपअप दिखाने की ज़िम्मेदारी एक अलग वस्तु को सौंपी जाती है। फैक्ट्री ऑब्जेक्ट निनजेक्ट से बात करने और मेरे लिए वस्तु प्राप्त करने के लिए ज़िम्मेदार है। यह प्रॉक्सी Ninject.Extensions.Factory परियोजना का उपयोग कर स्वचालित रूप से उत्पन्न होता है के रूप में मैं इस तरह एक अंतरफलक पारित:

/// <summary> 
/// Abstract Factory for creating Worksheet logic objects. Meant to be used with Ninject Factory extension. 
/// </summary> 
public interface IExpenseWorksheetFactory 
{ 
    ExpenseWorksheet CreateWorksheet(); 
    ExpenseWorksheet.ContextMenus CreateContextMenu(); 
    ExpenseWorksheet.Events CreateEventHandlers(); 
} 

आवेदन स्टार्टअप में, मैं बाइंडिंग को परिभाषित किया है और कारखाने के लिए ही बाध्यकारी:

//instantiate the kernel in app's Composition Root 
_kernel = new StandardKernel(); 

//worksheet related stuff - seems to be ok to be singleton 
_kernel.Bind<ExpenseWorksheet>().ToSelf().InSingletonScope(); 
_kernel.Bind<ExpenseWorksheet.Events>().ToSelf().InSingletonScope(); 
_kernel.Bind<ExpenseWorksheet.ContextMenus>().ToSelf().InSingletonScope(); 

//"automagic" factories 
_kernel.Bind<IExpenseWorksheetFactory>().ToFactory(); 

समस्या यह है:

मैं इस कारखाने को वीएसटीओ वर्कशीट के जेनरेट कोड में कैसे इंजेक्ट कर सकता हूं? मुझे वर्कशीट की स्टार्टअप विधि के अंदर _kernel.Get<IExpenseWorksheetFactory> पर कॉल करने का विचार पसंद नहीं है। क्या शीट 1 के सभी उपलब्ध उदाहरणों को देखना संभव है और कारखाने के इंजेक्शन को मजबूर करना संभव है?

उत्तर

2

लघु जवाब: नहीं

आप निर्माता इंजेक्शन, जो बेशक अधिक सुरुचिपूर्ण पढ़ता है की तरह कुछ के लिए देख रहे हैं। लेकिन जैसा कि है, यह यहां संभव नहीं है क्योंकि आपके पास VSTO एडिन में c'tor तक पहुंच नहीं है।

लेकिन वैसे भी, _kernel.Get<IExpenseWorksheetFactory> पर कॉल करने में इतना बुरा क्या है? आखिरकार, एक निर्भरता को हल करने के लिए स्पष्ट रूप से डी कंटेनर को कॉल करना सामान्य उपयोग मामलों में से एक है, और कोड-बैक फ़ाइल ठीक उसी के लिए बनाई गई है: तारों की चीजें ऊपर।

आप सही हैं, कोड-बैक में कोई व्यावसायिक तर्क नहीं होना चाहिए, लेकिन दूसरी ओर यह निश्चित रूप से में सभी चीजों को तारों को तार करने के लिए आवश्यक होना चाहिए। यह प्राथमिक कारण है कि यह क्यों मौजूद है। या, दूसरे शब्दों में:

मुझे लगता है कि आमतौर पर एक अच्छा अभ्यास कोड-बैक फाइलों में कोड से बचने के लिए होता है।

प्रत्येक मामले में सत्य नहीं है (लेकिन केवल उनमें से अधिकांश के लिए) और आपको इसे अधिक नहीं करना चाहिए। यदि आप ऐसा करते हैं, तो आप खुद को सिस्टम के खिलाफ लड़ेंगे - और याद रखें, सिस्टम हमेशा जीतता है; -) ...

+0

सहमत ... मुख्य ध्यान हमेशा व्यावसायिक समस्याओं को हल करना है, न कि लड़ाई प्रणाली और ढांचे के खिलाफ! –

+0

कन्स्ट्रक्टर इंजेक्शन कैसे संभव नहीं है? वीएसटीओ का स्टार्टअप इवेंट हैंडलर है जहां आप निंजा कॉन्फ़िगर करेंगे और फिर आप अपनी सभी सेवा और भंडार वस्तुओं के साथ-साथ रूपों के लिए DI का उपयोग करने में सक्षम हैं। –

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