共享的帮助程序库和MEF

时间:2018-08-31 15:58:43

标签: c# mef

我试图用C#创建一个基于插件的应用程序。现在,插件正在使用MEF进行发现。我遇到了一个问题,即主机应用程序和插件正在使用不同版本的通用库。

从高层次上讲,我想要n + 1个目录,一个用于主机,一个用于插件,并将插件或主机需要的所有文件都放在自己的文件夹中。

我有两种解决方案,一种是MEF接口,共享库和插件主机。第二个是MEF接口,共享库和插件实现。

这是我的问题的简化视图,显示出该行为:

如果我在共享库项目中更改ShowMessage的功能签名,然后仅重建插件实现解决方案,则在调用PrintInfo时会出现异常。我需要一种方法让插件主机加载一个版本,使插件实现可能具有第二个版本。

MEF接口项目

using System.ComponentModel.Composition;

namespace TestProject
{
    [InheritedExport(typeof(IPlugin))]
    public interface IPlugin
    {
        string Name { get; }

        void PrintInfo();
    }
}

共享库

using System.Windows.Forms;

namespace TestProject
{
    public class SharedLibrary
    {
#if true
        public static void ShowMessage(string message)
        {
            MessageBox.Show(message);
        }
#else
        public static void ShowMessage(string[] message)
        {
            string msg = String.Join("\n", message);
            MessageBox.Show(msg);
        }
#endif
    }
}

插件主机

using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Reflection;
using System.Windows.Forms;

namespace TestProject
{
    public partial class Form1 : Form
    {
        [ImportMany(typeof(IPlugin), AllowRecomposition = true)]
        List<IPlugin> allPlugins { get; set; }

        SharedLibrary sl = new SharedLibrary();

        public Form1()
        {
            InitializeComponent();

            AggregateCatalog catalog = new AggregateCatalog();
            DirectoryCatalog pluginDir = new DirectoryCatalog(@"..\..\..\Plugin\bin\Debug");
            catalog.Catalogs.Add(pluginDir);
            CompositionContainer container = new CompositionContainer(catalog);
            container.ComposeParts(this);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            string ver = Assembly.GetAssembly(sl.GetType()).GetName().Version.ToString();
            MessageBox.Show("Presenter version = " + ver);

            foreach (var plugin in allPlugins)
            {
                SharedLibrary.ShowMessage("Starting Plugin: " + plugin.Name);
                // this explodes when the shared library in the plugin directory doesn't match
                plugin.PrintInfo();
            }
        }
    }
}

插件实现

using System.Reflection;
using System.Windows.Forms;

namespace TestProject
{
    public class Plugin : IPlugin
    {
        public string Name { get; } = "Test Plugin";

        SharedLibrary sl = new SharedLibrary();

        public void PrintInfo()
        {
            string ver = Assembly.GetAssembly(sl.GetType()).GetName().Version.ToString();
            MessageBox.Show("Plugin version = " + ver);
#if true
            SharedLibrary.ShowMessage("I am a plugin" + "\n" + Assembly.GetExecutingAssembly().GetName().Version.ToString());
#else
            SharedLibrary.ShowMessage(new string[] { "I am a plugin", Assembly.GetExecutingAssembly().GetName().Version.ToString() });
#endif
        }
    }
}

0 个答案:

没有答案