我目前正在尝试用MEF构建一个简单的概念证明,但我无法让它工作。我的解决方案中有三个项目:
Component
)。一个.NET库,它定义一个派生自Button的类,并声明一个标有Component
属性的Import
类型的属性:
public class ComponentButton : Button
{
[Import]
public Component Component { get; set; }
}
一个WPF应用程序,其MainWindow具有ComponentButton类型的属性(标记为Export
),在构造函数中初始化。然后我想使用MEF将此组件分配给窗口中出现的所有按钮(目前只有一个在XAML中定义):
[Export]
public Component Component { get; private set; }
public MainWindow()
{
InitializeComponent();
this.Component = new Component();
var container = new CompositionContainer(new DirectoryCatalog(".", "*"));
try
{
container.ComposeParts(this);
}
catch (CompositionException compositionException)
{
Debugger.Break();
}
}
然而,这不起作用。不会抛出异常,但组件未分配给按钮。当我查看调试器中的目录时,我可以看到,虽然所有程序集都已加载并且它找到了ExportDefinition,但它找不到导入定义。但真正令我困惑的是,当我向按钮添加导出时,它突然检测到按钮的导出和导入:
[Export]
public string Dummy { get; set; }
但即便如此,它仍然没有将组件分配给按钮。发生了什么事?
答案 0 :(得分:1)
未设置按钮的属性,因为按钮是由WPF(通过InitializeComponent
调用)创建的,而不是由MEF创建的。从理论上讲,你可以浏览可视树并为每个对象调用container.SatisfyImportsOnce(obj)
,但这对于表现性能来说是一件可怕的事情。
一种解决方案是像往常一样使用绑定设置属性。但是,按钮可以执行自组合。你必须以某种方式暴露容器(例如通过静态属性)并在构造函数中自己调用SatisfyImportsOnce
按钮:
Global.MyCompositionContainer.SatisfyImportsOnce(this);
This question也可能会有所帮助。