[英]Using MEF with C#, how do I call methods on the host, from the plugin?
我正在嘗試使用Managed Extensibility Framework(MEF)框架向我的C#應用程序添加插件可擴展性,到目前為止它還可以; 我有我的主/主機應用程序從定義的文件夾加載插件,並可以從主應用程序調用他們的方法等。 宿主應用程序和插件都引用了一個單獨的dll程序集,其中包含所有項目通用的接口。
這工作正常,我可以從主應用程序調用/與插件交互。 但是,我也希望能夠從插件中與主機應用程序進行交互,但似乎無法了解如何完成此操作。
我希望能夠從我的插件中獲取/設置/執行主應用程序中的導出屬性和方法。 目前我只能從主應用程序“說出”插件,而不是相反。
我的代碼到目前為止:
接口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";
}
}
}
您可以在合同程序集中添加主機接口。 例如:
[InheritedExport]
public interface IHost
{
string Version { get; }
}
然后將類型為IHost的屬性添加到IPlugin接口:
[InheritedExport]
public interface IPlugin
{
IHost Host { get; }
String DoWork();
}
最后,每個插件都需要使用MEF的ImportAttribute來裝飾Host屬性:
[Import(typeof(IHost))]
public IHost Host { get; }
經過多次播放和反復試驗,我發現我遇到的問題是我沒有將當前正在執行的程序集( 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;
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.