MEF组成问题

时间:2012-09-13 08:16:31

标签: c# mef composition

我无法解决看似基本的MEF问题: 我有2个“插件”项目(我们称之为P1和P2),以及两个插件共用的第三个项目(我们称之为C)。 P1和P2都引用C。

尝试导入位于P1中的组件时,它会失败,因为此组件依赖于C中的组件。

这是跟踪:

  

System.ComponentModel.Composition警告:1:ComposablePartDefinition'MyCompany.Client.Pms.Plugin.InclusionList.ViewModel.InclusionListViewModel'已被拒绝。构图保持不变。由于以下错误,更改被拒绝:组合产生多个组合错误,有4个根本原因。根本原因如下。查看CompositionException.Errors属性以获取更多详细信息。

     

1)没有找到符合约束的导出'((exportDefinition.ContractName =“MyCompany.Client.Plugins.Common.Controls.Selectors.PortfolioSelectors.ViewModel.ICalypsoBookSelectorViewModel”)&& ;(exportDefinition.Metadata.ContainsKey(“ExportTypeIdentity”)&&&"“MyCompany.Client.Plugins.Common.Controls.Selectors.PortfolioSelectors.ViewModel.ICalypsoBookSelectorViewModel”.Equals(exportDefinition.Metadata.get_Item(“ExportTypeIdentity”))) )”

     

导致:无法设置导入'MyCompany.Client.Pms.Plugin.InclusionList.ViewModel.InclusionListViewModel.CalypsoBookSelectorViewModel(ContractName =“MyCompany.Client.Plugins.Common.Controls.Selectors.PortfolioSelectors.ViewModel.ICalypsoBookSelectorViewModel”)'on part'MyCompany.Client.Pms.Plugin.InclusionList.ViewModel.InclusionListViewModel'。   元素:MyCompany.Client.Pms.Plugin.InclusionList.ViewModel.InclusionListViewModel.CalypsoBookSelectorViewModel(ContractName =“MyCompany.Client.Plugins.Common.Controls.Selectors.PortfolioSelectors.ViewModel.ICalypsoBookSelectorViewModel”) - > MyCompany.Client.Pms.Plugin.InclusionList.ViewModel.InclusionListViewModel - > DirectoryCatalog(Path =“C:\ Work \ mmtrader \ dashboard \ Code \ Src \ Dashboard \ MM \ Trader \ bin \ Debug \ Plugins \ Positions”)

[...](其他3个问题在不同的视图模型上完全相同)

我查看了MEF目录,结果发现MEF知道那些视图模型,所以我不知道缺少什么。

根据Dennis的要求,以下是我的导入/导出:

导出:

Export(typeof(ICalypsoBookSelectorViewModel))]
public class CalypsoBookSelectorViewModel : ScreenWithCleanupLifecycle, ICalypsoBookSelectorViewModel
{...}

导入:

[Import(typeof(ICalypsoBookSelectorViewModel))]
public ICalypsoBookSelectorViewModel CalypsoBookSelectorViewModel { get; set; }

目录:

Catalog

提前感谢您的帮助!

4 个答案:

答案 0 :(得分:9)

我终于找到了问题,它与MEF指向的CalypsoBookSelectorViewModel无关。

实际上,ViewModel依赖于另一个组件(CalypsoBookSelectorModel),而该组件又依赖于IDispatcher组件。

问题是这个IDispatcher组件,用合同名称(见下文)指定,导出 TWICE (每个插件一次),所以MEF无法分辨哪一个使用。 真正的问题当然是 MEF应该告诉我,而不是将指针指向链上的两个级别。

感谢Dennis查看问题,我希望这会帮助那些会遇到同样问题的人。

Dispatcher导入:

[Import(DispatcherNames.BackgroundDispatcherName, typeof(IDispatcher))]
public IDispatcher Dispatcher { get; set; }

答案 1 :(得分:6)

您的P1C(更确切地说,ICalypsoBookSelectorViewModel)导入了一些内容。

当MEF容器尝试创建P1时,它还会尝试解析P1所依赖的所有导入。因此,它在自己的目录和父导出提供程序中执行ICalypsoBookSelectorViewModel类型的导出(实际上是合同名称,但在这种情况下无关紧要)。

如果未找到此类出口(这是您的情况),则MEF容器的成分保持不变 要解决此问题,您应该将[Export(typeof(ICalypsoBookSelectorViewModel))]添加到相应的类型定义中。

当然,所有这些都意味着您的目录和导出提供程序(如果有的话)已正确初始化。

请注意,此导出定义相等:

public interface IA {}

[Export(typeof(IA))] // contract name is "IA"
public class A : IA {}

[Export] // contract name is "A"
public class A : IA {}

[Export]
public class Composed
{
    [Import] // MEF will search for exports like [Export(typeof(IA))]
    private IA field1;

    [Import] // MEF will search for exports like [Export]
    private A field1;
}

答案 2 :(得分:0)

错误发生,因为他使用[Import],导入多个,您应该使用[ImportMany]

答案 3 :(得分:0)

进入后,我一直在寻找解决方案。我意识到我正在使用 System.Composition 而不是在导出类上使用 System.ComponentModel.Composition