当我更换零件时如何让 MEF 重新组合?
当我更新导出的实例时,我试图让 MEF 重构它所知道的所有部分。本质上,我想让 MEF 更新所有在更改时导入连接字符串配置值的部分。一切看起来都很好,直到我想更改实例。如果我尝试使用更新的值来 ComposeParts,它似乎会向容器中添加第二个部件实例,然后我的导入会更新,但为空。
谁能指出我哪里出错了?或者我应该尝试以这种方式使用 MEF?
我正在使用 MEF 预览版 9 并针对 .net Framework 3.5 和 WPF。
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Linq;
using System.Text;
using Shouldly;
namespace ConsoleApplication4
{
class Program
{
static void Main(string[] args)
{
MainClass main = new MainClass();
main.RunTest();
}
}
public class MainClass
{
[ImportMany]
public IEnumerable<Settings> Settings { get; set; }
public void RunTest()
{
AggregateCatalog catalog = new AggregateCatalog();
catalog.Catalogs.Add(new AssemblyCatalog(typeof(Settings).Assembly));
CompositionContainer container = new CompositionContainer(catalog);
container.SatisfyImportsOnce(this);
Config cfg = new Config
{
Settings = new Settings { ConnectionString = "Value1" },
};
// result is returned with a null settings value
UsesSettings result = container.GetExportedValue<UsesSettings>();
// this recomposes everything with the new value, result changes to have settings of Value1
container.ComposeParts(cfg);
// this line results in my import many enumerable returning 2 parts the Value1 setting and null
container.SatisfyImportsOnce(this);
result.TheSettings.ConnectionString.ShouldBe("Value1");
cfg.Settings = new Settings { ConnectionString = "Value2" };
// how do I tell the container to recompose now I have changed the config object,
// or how do I replace the part value with the new value?
// this line causes the result.Settings to return null
container.ComposeParts(cfg);
// this updates the ImportMany to 3 values, Value1, Value2 and null
container.SatisfyImportsOnce(this);
}
}
public class Settings
{
public string ConnectionString = "default value";
}
public class Config
{
[Export(typeof(Settings))]
public Settings Settings { get; set; }
}
[Export(typeof(UsesSettings))]
public class UsesSettings
{
[Import(typeof(Settings), AllowRecomposition = true)]
public Settings TheSettings { get; set; }
}
}
I am trying to get MEF to recompose all the parts that it knows about when I update an instance that is exported. Essentially I want to have MEF update all my parts that import a connection string configuration value when it is changed. Everything looks good up to the point where I want to change the instance. If I try to ComposeParts with the value updated it seems to add a second part instance into the container, and then my imports are updated, but to null.
Can anyone point out where I am going wrong? Or should I even be trying to use MEF in this fashion?
I am using MEF preview 9 and targetting .net framework 3.5, and WPF.
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Linq;
using System.Text;
using Shouldly;
namespace ConsoleApplication4
{
class Program
{
static void Main(string[] args)
{
MainClass main = new MainClass();
main.RunTest();
}
}
public class MainClass
{
[ImportMany]
public IEnumerable<Settings> Settings { get; set; }
public void RunTest()
{
AggregateCatalog catalog = new AggregateCatalog();
catalog.Catalogs.Add(new AssemblyCatalog(typeof(Settings).Assembly));
CompositionContainer container = new CompositionContainer(catalog);
container.SatisfyImportsOnce(this);
Config cfg = new Config
{
Settings = new Settings { ConnectionString = "Value1" },
};
// result is returned with a null settings value
UsesSettings result = container.GetExportedValue<UsesSettings>();
// this recomposes everything with the new value, result changes to have settings of Value1
container.ComposeParts(cfg);
// this line results in my import many enumerable returning 2 parts the Value1 setting and null
container.SatisfyImportsOnce(this);
result.TheSettings.ConnectionString.ShouldBe("Value1");
cfg.Settings = new Settings { ConnectionString = "Value2" };
// how do I tell the container to recompose now I have changed the config object,
// or how do I replace the part value with the new value?
// this line causes the result.Settings to return null
container.ComposeParts(cfg);
// this updates the ImportMany to 3 values, Value1, Value2 and null
container.SatisfyImportsOnce(this);
}
}
public class Settings
{
public string ConnectionString = "default value";
}
public class Config
{
[Export(typeof(Settings))]
public Settings Settings { get; set; }
}
[Export(typeof(UsesSettings))]
public class UsesSettings
{
[Import(typeof(Settings), AllowRecomposition = true)]
public Settings TheSettings { get; set; }
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
对于您想要完成的场景,您还有一些事情要做。
第一:如果您想添加/删除/更改特定导出,它不能位于目录本身中,因此您应该删除具有导出设置属性的 Config 类。这是由 CatalogExportProvider 创建的,也是您在集合中看到空值的原因。
请尝试以下操作:
You have a few things a little off for the scenario you are trying to accomplish.
First: If you want to add/remove/change a particular export it must not be in the catalog itself so you should remove your Config class which has the Export settings property. That is being created by the CatalogExportProvider and is the reason you are seeing a null value in your collection.
Try the following: