我无法解决看似基本的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; }
目录:
提前感谢您的帮助!
答案 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)
您的P1
从C
(更确切地说,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 。