8

我无法解决看似基本的 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”部分设置导入“MyCompany.Client.Pms.Plugin.InclusionList.ViewModel.InclusionListViewModel.CalypsoBookSelectorViewModel (ContractName="MyCompany.Client.Plugins.Common.Controls.Selectors.PortfolioSelectors.ViewModel.ICalypsoBookSelectorViewModel")' .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 知道这些视图模型,所以我不知道缺少什么。

根据下面丹尼斯的要求,这是我的导入/导出:

出口:

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

进口:

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

和目录:

目录

在此先感谢您的帮助!

4

4 回答 4

9

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

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

问题是这个 IDispatcher 组件,它是用合同名称指定的(见下文),被导出了两次(在每个插件中一次),所以 MEF 无法确定使用哪一个。真正的问题当然是MEF 应该告诉我,而不是把矛头指向链上两级的班级。

感谢丹尼斯查看问题,我希望这会帮助其他遇到同样问题的人。

调度程序导入:

[Import(DispatcherNames.BackgroundDispatcherName, typeof(IDispatcher))]
public IDispatcher Dispatcher { get; set; }
于 2012-09-13T09:23:27.403 回答
6

您从(更准确地说,) P1进口一些东西。CICalypsoBookSelectorViewModel

当 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;
}
于 2012-09-13T08:42:17.593 回答
0

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

于 2020-04-24T09:57:39.050 回答
0

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

于 2017-08-22T21:27:00.280 回答