2013-10-24 3 views
5

Managed Extensibility Framework (MEF)フレームワークを使用して、C#アプリケーションにプラグインの拡張性を追加しようとしています。私は定義されたフォルダからメイン/ホストアプリケーションのプラグインを読み込み、メインアプリケーションからメソッドなどを呼び出すことができます。ホストアプリケーションとプラグインは、すべてのプロジェクトに共通のインタフェースを含む個別のdllアセンブリを参照します。C#で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")); 
     } 
    } 
} 

プラグイン

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のプロパティを追加します。

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

最後に各プラグインは、MEFのImportAttributeでホストプロパティを飾るために必要があります。

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

ありがとうございます。私はちょうどこれと一緒に行ったことがありますが、残念ながら成功していません(エラーはありません。私は何かが欠けているに違いないと思う。ホストアプリケーションでのIHostの正しい実装は何ですか?どのように公開されるべきですか? – Alfie

関連する問題