5

我正在尝试使用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";
        }
    }
}
4

2 回答 2

4

您可以在合同程序集中添加主机接口。例如:

[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; }
于 2013-10-27T10:35:44.743 回答
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;
        }
    }
}
于 2013-10-28T13:05:52.287 回答