MEF插件没有来自主机的数据

本文关键字:主机 数据 插件 MEF | 更新日期: 2023-09-27 17:57:54

我试图将配置数据从主机放入插件,但插件总是为null。我负责插件的代码如下:

形式:

public partial class MyForm : Form
{
    public MyForm()
    {
        InitializeComponent();
        DataStorage.Instance.LoadModes();
        DataStorage.Instance.ActiveMode = "aaa";
        DataStorage.Instance.RulesFile = "bbb";
        DataStorage.Instance.SetProjectName("cccc");
        DataStorage.Instance.LoadRules();
        DataStorage.Instance.LoadPlugins();
    }
}

数据存储:

[PartCreationPolicy(CreationPolicy.Shared)]
[Export(typeof(ConfigStorage))]  
public class DataStorage: ConfigStorage
{
    //fields and properties here
    public string ActiveMode;
    [ImportMany(typeof (IAPlugin))]
    public IEnumerable<Lazy<IAPlugin, IAPluginData>> aPlugins;
    [ImportMany(typeof (IBPlugin))]
    public IEnumerable<Lazy<IBPlugin, IBPluginData>> bPlugins;
    private CompositionContainer _container;
    private static readonly DataStorage instance = new DataStorage();
    static DataStorage()
    {
    }
    private DataStorage()
    {
            Init();
    }

    public static DataStorage Instance
    {
        get { return instance; }
    }

    private void Init()
    {
        //code here
    }
    public void LoadPlugins()
    {
        var catalog = new AggregateCatalog();
        catalog.Catalogs.Add(new AssemblyCatalog(typeof(ConfigStorage).Assembly));
        catalog.Catalogs.Add(new DirectoryCatalog(Settings.Default.GetPathFor("Plugins")));
        _container = new CompositionContainer(catalog);
        try
        {
            _container.ComposeParts(this);
        }
        catch (CompositionException compositionException)
        {
            Console.WriteLine(compositionException.ToString());
        }
    }
}

ConfigStorage:

public abstract class ConfigStorage
{
    public string RulesFile;
    public string ActiveMode;
//properties and methods
}

插件:

[Export(typeof (IAPlugin))]
[ExportMetadata("Name", "myNameIsBond")]
public class myNameIsBond :  IAPlugin
{
     protected readonly ConfigStorage configStorage;
     [ImportingConstructor]
     public myNameIsBond (ConfigStorage configStorage)
    {
        if (configStorage == null)
            throw new ArgumentNullException("configStorage");
        this.configStorage = configStorage;
    }

    public string DoStep(string url)
    {
        Console.WriteLine(configStorage.ActiveMode); //this is null - it should be "aaa"
        return url;
    }
}

当我运行插件时。价值DoStep("某事")控制台。WriteLine(configStorage.ActiveMode)总是打印null-当我调试时:configStorage中的所有字段都是null。我做错了什么?如何将DataStorage实例放入插件?

MEF插件没有来自主机的数据

我认为问题是ConfigStorage导出显示在目录中,因此导入对目录创建的版本而不是您配置的singleton感到满意。请尝试在DataStorage类上放置PartNotDiscoverableAttribute。

顺便说一句,DataStorage构造函数是私有的,但看起来目录仍然可以创建它的单独版本,因为构造函数是通过反射调用的。

我通常根本不使用实例变量,只让MEF创建singleton,但如果你真的想拥有实例属性,你可以做一些类似的事情

// note that there is no export attribute here
public class DataStorage: ConfigStorage
{
    [Export(typeof(ConfigStorage))] 
    public static DataStorage instance { get; private set; }
}

这样MEF将导出您的singleton实例,而不是创建一个新对象。

相关文章: