我有一个非常简单的应用程序,只有一个导出和多个相同类型的导入。
在我调用ComposeParts之后,我可以看到导入在我调用ComposeParts的同一个类中工作 - MyService属性已被连接。
问题是我有另一个需要访问MyService的UserControl并且没有设置属性 - 它在同一个包中等但是在我调用ComposeParts时没有实例化。
如果我将CompositionContainer设为public / static并调用ComposeParts并传递UserControl,则设置MyService属性,但这是一个可怕的解决方案。
任何人都可以了解正在发生的事情吗? ComposeParts是否足够智能以挂接现有对象,或者导入属性是否能够在以后处理对象?我错误地挂了什么东西吗?
public partial class App : Application
{
protected override void OnActivated(EventArgs e)
{
AssemblyCatalog assemblyCatalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
compositionContainer = new CompositionContainer(assemblyCatalog);
compositionContainer.ComposeParts(this);
}
[Import(typeof(MyService))]
public MyService MyService { get; set; }
}
我正在尝试将.b 2.0中的服务提供商模型的250k行C#项目升级到MEF。
似乎您无法通过Import属性自动将新对象实例连接到它所需的服务。看起来你需要重新触发ComposeParts或类似的东西。跛。
在.Net 2.0提供程序/容器模型中,您需要将子对象显式添加到父容器,并且查找服务将是从子容器到父容器的递归检查。我不确定MEF中的证据是什么?
答案 0 :(得分:1)
看起来像问题的一件事是你的目录中只有一个程序集(正在执行的程序集)。如果这是一个单组装项目,其中所有[Export]
项都在同一个程序集中,那么它将正常工作。如果没有,那么您需要将所有程序集传递到目录中或使用DirectoryCatalog
。
您可以使用UserControl
标记[Export]
类,然后使用CompositionContainer.GetExportedValue()
创建UserControl
并完成其[Import]
,而不是调用其构造函数一次性需要。但是,如果表单在设计时已经具有控件,那么对于UI来说这并不总是可行的。在这种情况下,您必须调用ComposeParts来设置[Import]
值。
这实际上归结为您如何在应用程序中设置UserControl
类。如果您在运行时连接它,那么您有机会挂钩到CompositionContainer为您创建实例并自动连接它们。如果您依靠设计时代码来设置控件,那么您需要使用GetService()
来电替换所有ComposeParts()
来电。
答案 1 :(得分:0)
您可以在Codeplex上查看动态挂钩的 dI.Hook 框架