MEF 插件没有来自主机的数据
我试图将配置数据从主机放入插件,但我总是在插件处得到空值。我负责插件的代码如下:
Form:
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();
}
}
DataStorage:
[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
}
Plugin:
[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;
}
}
当我运行 plugin.Value.DoStep("sth"); the Console.WriteLine(configStorage.ActiveMode); 总是打印 null - 当我调试时:configStorage 中的所有字段都是 null。我做错了什么?如何将 DataStorage 实例放入我的插件中?
I'm trying to put config data from host to plugins but I always get nulls at plugins. My code responsible for plugins is below:
Form:
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();
}
}
DataStorage:
[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
}
Plugin:
[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;
}
}
When I run plugin.Value.DoStep("sth"); the Console.WriteLine(configStorage.ActiveMode); always print null - when I debugging: all fields from configStorage are nulls. What I'm doing wrong? How can I put DataStorage instance to my plugins?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为问题在于 ConfigStorage 导出显示在目录中,因此导入对目录创建的版本而不是您配置的单例感到满意。尝试将 PartNotDiscoverableAttribute 放在 DataStorage 类上。
顺便说一句,您的 DataStorage 构造函数是私有的,但看起来目录仍然可以创建它的单独版本,因为构造函数是通过反射调用的。
I think the problem is that the ConfigStorage export is showing up in the catalog, so the imports are getting satisfied with a version created by the catalog instead of the singleton you have configured. Try putting a PartNotDiscoverableAttribute on the DataStorage class.
As an aside, your DataStorage constructor is private, but it looks like the catalog can still create a separate version of it because the constructor is invoked through reflection.
我通常根本不使用实例变量,只是让 MEF 创建单例,但如果您确实想要拥有实例属性,您可以执行类似的操作
,以便 MEF 将导出您的单例实例而不是创建新对象。
I typically don't use an instance variable at all and just let MEF create the singleton, but if you really want to have an instance property you can do something like
So that MEF will export your singleton instance rather than creating a new object.