2013-10-24 5 views
5

मैं Managed Extensibility Framework (MEF) ढांचे का उपयोग कर अपने सी # एप्लिकेशन में प्लगइन विस्तारशीलता जोड़ने की कोशिश कर रहा हूं, और अब तक यह ठीक हो रहा है; मेरे पास एक मुख्य फ़ोल्डर से मेरा मुख्य/होस्ट एप्लिकेशन लोडिंग प्लगइन्स है, और मुख्य अनुप्रयोग से उनकी विधियों आदि को कॉल कर सकता है। होस्ट होस्ट और प्लगइन्स दोनों एक अलग डीएल असेंबली का संदर्भ देते हैं जिसमें सभी परियोजनाओं के लिए आम इंटरफेस शामिल होते हैं।सी # के साथ एमईएफ का उपयोग, मैं प्लगइन से मेजबान पर विधियों को कैसे कॉल करूं?

यह ठीक काम कर रहा है और मैं मुख्य एप्लिकेशन से प्लगइन से कॉल/बातचीत कर सकता हूं। हालांकि, मैं प्लगइन के से होस्ट एप्लिकेशन से इंटरैक्ट करने में सक्षम होना चाहूंगा, लेकिन ऐसा नहीं लगता कि यह कैसे किया जाता है।

मैं अपने प्लगइन से मुख्य ऐप में निर्यात किए गए गुणों और विधियों को प्राप्त/सेट/निष्पादित करने में सक्षम होना चाहता हूं। वर्तमान में मैं मुख्य ऐप से प्लगइन को 'बोलने' में सक्षम हूं, न कि दूसरी तरफ भी।

मेरे कोड इस प्रकार अब तक:

इंटरफ़ेस DLL

namespace MefContracts 
{ 
    [InheritedExport] 
    public interface IPlugin 
    { 
     String DoWork(); 
    } 

    public class Class1 
    { 
     public IPlugin plugin { get; set; } 
    } 
} 

मुख्य/होस्ट आवेदन

namespace MyMEF 
{ 
    class clsMEF 
    { 
     private CompositionContainer _container; 

     [Import(typeof(MefContracts.IPlugin))] 
     public MefContracts.IPlugin plugin; 

     public clsMEF() 
     { 
      Compose(); 
     } 

     void Compose() 
     { 
      var catalog = new AggregateCatalog(); 
      catalog.Catalogs.Add(new DirectoryCatalog("..\\..\\Extensions")); 
      _container = new CompositionContainer(catalog); 
      try 
      { 
       this._container.ComposeParts(this); 
      } 
      catch (CompositionException compositionException) 
      { 
       Console.WriteLine(compositionException.ToString()); 
      } 
     } 
    } 

    void Main() 
    { 
     clsMEF myMef = new clsMEF(); 
     MessageBox.Show(myMef.plugin.DoWork()); 
    } 
} 

प्लगइन

namespace MefPlugin 
{ 
    [Export] 
    public class Class1 : MefContracts.IPlugin 
    { 

     public String DoWork() 
     { 
      return "Plugin called"; 
     } 
    } 
} 

उत्तर

3

बहुत अधिक खेल और परीक्षण और त्रुटि के बाद, मुझे वह समस्या मिली जो मैंने किया था, मैंने मेजबान की असेंबली कैटलॉग में वर्तमान निष्पादन असेंबली (System.Reflection.Assembly.GetExecutingAssembly()) को जोड़ा नहीं था प्लगइन की असेंबली।

@PanosRontogiannis के लिए बहुत धन्यवाद जिन्होंने मुझे सही लाइनों पर पहुंचाया - यह जवाब असेंबली ठीक से जोड़े जाने के बाद शानदार ढंग से काम करता था।

इंटरफ़ेस DLL

using System.ComponentModel.Composition; 

namespace MefContracts 
{ 
    [InheritedExport] 
    public interface IPlugin 
    { 
     String Work(String input); 
    } 

    [InheritedExport] 
    public interface IHost 
    { 
     string Version { get; } 
    } 
} 

होस्ट आवेदन

using System.ComponentModel.Composition; 
using System.ComponentModel.Composition.Hosting; 

namespace MyMEF 
{ 

    [Export] 
    public class Class1 : MefContracts.IHost 
    { 
     public String Version 
     { 
      get { return "v1.00"; } 
     } 
    } 

    class clsMEF 
    { 
     private CompositionContainer _container; 

     [Import(typeof(MefContracts.IPlugin))] 
     public MefContracts.IPlugin plugin; 

     public clsMEF() 
     { 
      Compose(); 
     } 

     void Compose() 
     { 
      var catalog = new AggregateCatalog(); 
      catalog.Catalogs.Add(new DirectoryCatalog("..\\..\\Extensions")); 
      catalog.Catalogs.Add(new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly())); // <-- THIS WAS THE MISSING PIECE 
      _container = new CompositionContainer(catalog); 
      try 
      { 
       this._container.ComposeParts(this); 
      } 
      catch (CompositionException compositionException) 
      { 
       Console.WriteLine(compositionException.ToString()); 
      } 

     } 
    } 
    static class Program 
    { 
     static void Main() 
     { 
      clsMEF myMef = new clsMEF(); 
      MessageBox.Show(myMef.plugin.Work("My Input")); 
     } 
    } 
} 

प्लगइन

:

यहाँ जरूरत में दूसरों के लिए काम कर रहे कोड है 0

using System.ComponentModel.Composition; 

namespace MefPlugin 
{ 
    [Export] 
    public class Class2 : MefContracts.IPlugin 
    { 
     [Import(typeof(MefContracts.IHost))] 
     public MefContracts.IHost Host; 

     public String Work(String input) 
     { 
      return "Plugin Called (Input: " + input + "). Host Application Version: " + input + Host.Version; 
     } 
    } 
} 
+0

मेरा होस्ट सदस्य कभी पॉप्युलेट नहीं होता है। क्या आपने कभी सामना किया था? – jsmith

+0

@jsmith - देर से उत्तर के लिए खेद है, लेकिन मुझे लगता है कि यह इस समय का सामना करने वाली प्रारंभिक समस्या थी। यदि आपने पहले ही इसे हल नहीं किया है और यहां अपना कोड किसी अन्य प्रश्न पर पोस्ट करना चाहते हैं और यहां लिंक करना चाहते हैं तो मुझे एक नज़र डालने में खुशी होगी। – Alfie

4

आप अनुबंध असेंबली में एक होस्ट इंटरफ़ेस जोड़ सकते हैं। उदाहरण के लिए:

[InheritedExport] 
public interface IHost 
{ 
    string Version { get; } 
} 

फिर IPlugin अंतरफलक के प्रकार iHost की कोई प्रॉपर्टी जोड़ते हैं:

[Import(typeof(IHost))] 
public IHost Host { get; } 
:

[InheritedExport] 
public interface IPlugin 
{ 
    IHost Host { get; } 
    String DoWork(); 
} 

अंत में प्रत्येक प्लग में MEF के ImportAttribute साथ होस्ट संपत्ति को सजाने के लिए की आवश्यकता होगी

+0

आपके उत्तर के लिए धन्यवाद।मैंने अभी इसके साथ जाना है लेकिन दुर्भाग्य से सफलता के बिना (कोई त्रुटि नहीं, बस कुछ भी वापस नहीं मिल रहा है)। मुझे लगता है कि मुझे कुछ याद आना चाहिए; मेजबान आवेदन में IHost का सही कार्यान्वयन क्या है? इसे कैसे उजागर किया जाना चाहिए? – Alfie

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

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