在使用[Import(AllowDefault = true)]之前,不会调用MEF [ImportingConstructor]

时间:2013-03-26 20:29:53

标签: c# mef composition

我正在使用MEF1并进入一个奇怪的场景。

永远不会调用此构造函数:

[ImportingConstructor]
public LogViewModuleRoot(INavigationCommandManager navigationCommandManager,
                         ISettingsManager settingsManager,
                         IBusyService busyService)
{
    NavigationCommandManager = navigationCommandManager;
    SettingsManager = settingsManager;
    BusyService = busyService;
}

在更改为此时,使用正确的值调用构造函数:

[ImportingConstructor]
public LogViewModuleRoot(INavigationCommandManager navigationCommandManager,
                         ISettingsManager settingsManager,
                         [Import(AllowDefault = true)] IBusyService busyService)
{
    NavigationCommandManager = navigationCommandManager;
    SettingsManager = settingsManager;
    BusyService = busyService; // Properly hydrated - i.e. not null
}

通常,如果没有匹配的导出,则不会调用ImportingConstructor,但如果没有匹配的导出,则当 AllowDefault 设置为时,将无法加载是的

哪些问题可能导致此行为?

如果这与组合图中的循环依赖关系以及构建 IBusyService 的时间有关,是否有工具可以找到问题的根源?

更新

似乎没有深度循环依赖。即使IBusyService的导出没有自己的导入,问题仍然存在。另请注意,导出的IBusyService实例在此ImportingConstructor尝试运行之前很久就会加载。

其他信息

使用MEFX Visualizer,两个案例都表明没有构图问题,并且所有导入都得到满足。

这是MEFX CompositionInfo的输出:

[Part] ****.Modularity.Logging.CallbackLogger from: AssemblyCatalog (Assembly="****.Modularity.Mef, Version=2.4.0.347, Culture=neutral, PublicKeyToken=null")
  [Export] ****.Modularity.Logging.CallbackLogger (ContractName="****.Modularity.Logging.CallbackLogger")

[Part] ****.Modularity.Modules.ModuleManager from: AssemblyCatalog (Assembly="****.Modularity.Mef, Version=2.4.0.347, Culture=neutral, PublicKeyToken=null")
  [Export] ****.Modularity.Modules.ModuleManager (ContractName="****.Modularity.Modules.IModuleManager")
  [Import] ****.Modularity.Modules.ModuleManager.ImportedModules (ContractName="****.Modularity.IModule")
    [SatisfiedBy] Debug.Module.ModuleRoot (ContractName="****.Modularity.IModule") from: Debug.Module.ModuleRoot from: AssemblyCatalog (Assembly="Debug.Module, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")
    [Unsuitable] Logging.Module.LogConfigurationModuleRoot (ContractName="****.Modularity.IModule") from: Logging.Module.LogConfigurationModuleRoot from: AssemblyCatalog (Assembly="Logging.Module, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")
    [Unsuitable] Logging.Module.LogViewModuleRoot (ContractName="****.Modularity.IModule") from: Logging.Module.LogViewModuleRoot from: AssemblyCatalog (Assembly="Logging.Module, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")
  [Import] ****.Modularity.Modules.ModuleManager..ctor (Parameter="moduleCatalog", ContractName="****.Modularity.Modules.IModuleCatalog")
    [SatisfiedBy] ****.Modularity.Modules.IModuleCatalog
  [Import] ****.Modularity.Modules.ModuleManager..ctor (Parameter="logger", ContractName="****.Modularity.Logging.ILogger")
    [SatisfiedBy] ****.Modularity.Logging.ILogger
  [Import] ****.Modularity.Modules.ModuleManager..ctor (Parameter="exServiceLocator", ContractName="****.Modularity.IExtendedServiceLocator")
    [SatisfiedBy] ****.Modularity.IExtendedServiceLocator

[Part] ****.Modularity.Shells.ConsoleShell from: AssemblyCatalog (Assembly="****.Modularity.Shells, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")
  [Export] ****.Modularity.Shells.ConsoleShell (ContractName="****.Modularity.Shells.ConsoleShell")
  [Import] ****.Modularity.Shells.ConsoleShell..ctor (Parameter="navigationManager", ContractName="****.Modularity.Windows.Navigation.INavigationManager")
    [SatisfiedBy] ****.Modularity.Windows.Navigation.NavigationManager (ContractName="****.Modularity.Windows.Navigation.INavigationManager") from: ****.Modularity.Windows.Navigation.NavigationManager from: AssemblyCatalog (Assembly="****.Modularity.Windows, Version=2.4.0.347, Culture=neutral, PublicKeyToken=null")
  [Import] ****.Modularity.Shells.ConsoleShell..ctor (Parameter="logger", ContractName="****.Modularity.Logging.CallbackLogger")
    [SatisfiedBy] ****.Modularity.Logging.CallbackLogger (ContractName="****.Modularity.Logging.CallbackLogger") from: ****.Modularity.Logging.CallbackLogger from: AssemblyCatalog (Assembly="****.Modularity.Mef, Version=2.4.0.347, Culture=neutral, PublicKeyToken=null")
  [Import] ****.Modularity.Shells.ConsoleShell..ctor (Parameter="locator", ContractName="****.Modularity.IExtendedServiceLocator")
    [SatisfiedBy] ****.Modularity.IExtendedServiceLocator
  [Import] ****.Modularity.Shells.ConsoleShell..ctor (Parameter="viewModel", ContractName="****.Modularity.Shells.ViewModel.ShellViewModel")
    [SatisfiedBy] ****.Modularity.Shells.ViewModel.ShellViewModel (ContractName="****.Modularity.Shells.ViewModel.ShellViewModel") from: ****.Modularity.Shells.ViewModel.ShellViewModel from: AssemblyCatalog (Assembly="****.Modularity.Shells, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")

[Part] ****.Modularity.Shells.****LegacyNavigation from: AssemblyCatalog (Assembly="****.Modularity.Shells, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")
  [Export] ****.Modularity.Shells.****LegacyNavigation (ContractName="****.Modularity.Shells.****LegacyNavigation")
  [Import] ****.Modularity.Shells.****LegacyNavigation..ctor (Parameter="navigationManager", ContractName="****.Modularity.Windows.Navigation.INavigationManager")
    [SatisfiedBy] ****.Modularity.Windows.Navigation.NavigationManager (ContractName="****.Modularity.Windows.Navigation.INavigationManager") from: ****.Modularity.Windows.Navigation.NavigationManager from: AssemblyCatalog (Assembly="****.Modularity.Windows, Version=2.4.0.347, Culture=neutral, PublicKeyToken=null")
  [Import] ****.Modularity.Shells.****LegacyNavigation..ctor (Parameter="logger", ContractName="****.Modularity.Logging.CallbackLogger")
    [SatisfiedBy] ****.Modularity.Logging.CallbackLogger (ContractName="****.Modularity.Logging.CallbackLogger") from: ****.Modularity.Logging.CallbackLogger from: AssemblyCatalog (Assembly="****.Modularity.Mef, Version=2.4.0.347, Culture=neutral, PublicKeyToken=null")
  [Import] ****.Modularity.Shells.****LegacyNavigation..ctor (Parameter="locator", ContractName="****.Modularity.IExtendedServiceLocator")
    [SatisfiedBy] ****.Modularity.IExtendedServiceLocator
  [Import] ****.Modularity.Shells.****LegacyNavigation..ctor (Parameter="dataContext", ContractName="****.Modularity.Windows.Shell.IShellDataContext")
    [SatisfiedBy] ****.Modularity.Shells.ViewModel.ShellViewModel (ContractName="****.Modularity.Windows.Shell.IShellDataContext") from: ****.Modularity.Shells.ViewModel.ShellViewModel from: AssemblyCatalog (Assembly="****.Modularity.Shells, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")

[Part] ****.Modularity.Shells.KioskShell from: AssemblyCatalog (Assembly="****.Modularity.Shells, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")
  [Export] ****.Modularity.Shells.KioskShell (ContractName="****.Modularity.Shells.KioskShell")
  [Import] ****.Modularity.Shells.KioskShell..ctor (Parameter="navigationManager", ContractName="****.Modularity.Windows.Navigation.INavigationManager")
    [SatisfiedBy] ****.Modularity.Windows.Navigation.NavigationManager (ContractName="****.Modularity.Windows.Navigation.INavigationManager") from: ****.Modularity.Windows.Navigation.NavigationManager from: AssemblyCatalog (Assembly="****.Modularity.Windows, Version=2.4.0.347, Culture=neutral, PublicKeyToken=null")
  [Import] ****.Modularity.Shells.KioskShell..ctor (Parameter="logger", ContractName="****.Modularity.Logging.CallbackLogger")
    [SatisfiedBy] ****.Modularity.Logging.CallbackLogger (ContractName="****.Modularity.Logging.CallbackLogger") from: ****.Modularity.Logging.CallbackLogger from: AssemblyCatalog (Assembly="****.Modularity.Mef, Version=2.4.0.347, Culture=neutral, PublicKeyToken=null")
  [Import] ****.Modularity.Shells.KioskShell..ctor (Parameter="dataContext", ContractName="****.Modularity.Windows.Shell.IShellDataContext")
    [SatisfiedBy] ****.Modularity.Shells.ViewModel.ShellViewModel (ContractName="****.Modularity.Windows.Shell.IShellDataContext") from: ****.Modularity.Shells.ViewModel.ShellViewModel from: AssemblyCatalog (Assembly="****.Modularity.Shells, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")

[Part] ****.Modularity.Shells.ViewModel.ShellViewModel from: AssemblyCatalog (Assembly="****.Modularity.Shells, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")
  [Export] ****.Modularity.Shells.ViewModel.ShellViewModel (ContractName="****.Modularity.Windows.Shell.IShellDataContext")
  [Export] ****.Modularity.Shells.ViewModel.ShellViewModel (ContractName="****.Modularity.Windows.Commanding.INavigationContext")
  [Export] ****.Modularity.Shells.ViewModel.ShellViewModel (ContractName="****.Modularity.Windows.IBusyService")
  [Export] ****.Modularity.Shells.ViewModel.ShellViewModel (ContractName="****.Modularity.Shells.ViewModel.ShellViewModel")
  [Import] ****.Modularity.Shells.ViewModel.ShellViewModel..ctor (Parameter="navigationCommandManager", ContractName="****.Modularity.Windows.Commanding.INavigationCommandManager")
    [SatisfiedBy] ****.Modularity.Windows.Commanding.INavigationCommandManager
    [Unsuitable] ****.Modularity.Windows.Commanding.NavigationCommandManager (ContractName="****.Modularity.Windows.Commanding.INavigationCommandManager") from: ****.Modularity.Windows.Commanding.NavigationCommandManager from: AssemblyCatalog (Assembly="****.Modularity.Windows, Version=2.4.0.347, Culture=neutral, PublicKeyToken=null")
  [Import] ****.Modularity.Shells.ViewModel.ShellViewModel..ctor (Parameter="menuCommandManager", ContractName="****.Modularity.Windows.IMenuCommandManager")
    [SatisfiedBy] ****.Modularity.Windows.Commanding.MenuCommandManager (ContractName="****.Modularity.Windows.IMenuCommandManager") from: ****.Modularity.Windows.Commanding.MenuCommandManager from: AssemblyCatalog (Assembly="****.Modularity.Windows, Version=2.4.0.347, Culture=neutral, PublicKeyToken=null")
  [Import] ****.Modularity.Shells.ViewModel.ShellViewModel..ctor (Parameter="applicationInformation", ContractName="****.Modularity.Shells.IApplicationInformation")
    [SatisfiedBy] ****.Modularity.Shells.IApplicationInformation
  [Import] ****.Modularity.Shells.ViewModel.ShellViewModel..ctor (Parameter="manager", ContractName="****.Modularity.Modules.IModuleManager")
    [SatisfiedBy] ****.Modularity.Modules.ModuleManager (ContractName="****.Modularity.Modules.IModuleManager") from: ****.Modularity.Modules.ModuleManager from: AssemblyCatalog (Assembly="****.Modularity.Mef, Version=2.4.0.347, Culture=neutral, PublicKeyToken=null")
  [Import] ****.Modularity.Shells.ViewModel.ShellViewModel..ctor (Parameter="actionExecuter", ContractName="****.Modularity.IActionExecuter")
    [SatisfiedBy] ****.Modularity.IActionExecuter

[Part] ****.Modularity.Windows.Commanding.MenuCommandManager from: AssemblyCatalog (Assembly="****.Modularity.Windows, Version=2.4.0.347, Culture=neutral, PublicKeyToken=null")
  [Export] ****.Modularity.Windows.Commanding.MenuCommandManager (ContractName="****.Modularity.Windows.IMenuCommandManager")
  [Import] ****.Modularity.Windows.Commanding.MenuCommandManager..ctor (Parameter="moduleManager", ContractName="****.Modularity.Modules.IModuleManager")
    [SatisfiedBy] ****.Modularity.Modules.ModuleManager (ContractName="****.Modularity.Modules.IModuleManager") from: ****.Modularity.Modules.ModuleManager from: AssemblyCatalog (Assembly="****.Modularity.Mef, Version=2.4.0.347, Culture=neutral, PublicKeyToken=null")
  [Import] ****.Modularity.Windows.Commanding.MenuCommandManager..ctor (Parameter="navigationManager", ContractName="****.Modularity.Windows.Navigation.INavigationManager")
    [SatisfiedBy] ****.Modularity.Windows.Navigation.NavigationManager (ContractName="****.Modularity.Windows.Navigation.INavigationManager") from: ****.Modularity.Windows.Navigation.NavigationManager from: AssemblyCatalog (Assembly="****.Modularity.Windows, Version=2.4.0.347, Culture=neutral, PublicKeyToken=null")

    [Part] ****.Modularity.Windows.Commanding.NavigationCommandManager from: AssemblyCatalog (Assembly="****.Modularity.Windows, Version=2.4.0.347, Culture=neutral, PublicKeyToken=null")
      [Export] ****.Modularity.Windows.Commanding.NavigationCommandManager (ContractName="****.Modularity.Windows.Commanding.INavigationCommandManager")
      [Import] ****.Modularity.Windows.Commanding.NavigationCommandManager..ctor (Parameter="moduleManager", ContractName="****.Modularity.Modules.IModuleManager")
        [SatisfiedBy] ****.Modularity.Modules.ModuleManager (ContractName="****.Modularity.Modules.IModuleManager") from: ****.Modularity.Modules.ModuleManager from: AssemblyCatalog (Assembly="****.Modularity.Mef, Version=2.4.0.347, Culture=neutral, PublicKeyToken=null")
      [Import] ****.Modularity.Windows.Commanding.NavigationCommandManager..ctor (Parameter="navigationManager", ContractName="****.Modularity.Windows.Navigation.INavigationManager")
        [SatisfiedBy] ****.Modularity.Windows.Navigation.NavigationManager (ContractName="****.Modularity.Windows.Navigation.INavigationManager") from: ****.Modularity.Windows.Navigation.NavigationManager from: AssemblyCatalog (Assembly="****.Modularity.Windows, Version=2.4.0.347, Culture=neutral, PublicKeyToken=null")

    [Part] ****.Modularity.Windows.Commanding.MenuNavigationCommandManager from: AssemblyCatalog (Assembly="****.Modularity.Windows, Version=2.4.0.347, Culture=neutral, PublicKeyToken=null")
      [Export] ****.Modularity.Windows.Commanding.MenuNavigationCommandManager (ContractName="****.Modularity.Windows.Commanding.MenuNavigationCommandManager")
      [Import] ****.Modularity.Windows.Commanding.MenuNavigationCommandManager..ctor (Parameter="moduleManager", ContractName="****.Modularity.Modules.IModuleManager")
        [SatisfiedBy] ****.Modularity.Modules.ModuleManager (ContractName="****.Modularity.Modules.IModuleManager") from: ****.Modularity.Modules.ModuleManager from: AssemblyCatalog (Assembly="****.Modularity.Mef, Version=2.4.0.347, Culture=neutral, PublicKeyToken=null")
      [Import] ****.Modularity.Windows.Commanding.MenuNavigationCommandManager..ctor (Parameter="navigationManager", ContractName="****.Modularity.Windows.Navigation.INavigationManager")
        [SatisfiedBy] ****.Modularity.Windows.Navigation.NavigationManager (ContractName="****.Modularity.Windows.Navigation.INavigationManager") from: ****.Modularity.Windows.Navigation.NavigationManager from: AssemblyCatalog (Assembly="****.Modularity.Windows, Version=2.4.0.347, Culture=neutral, PublicKeyToken=null")
      [Import] ****.Modularity.Windows.Commanding.MenuNavigationCommandManager..ctor (Parameter="menuCommandManager", ContractName="****.Modularity.Windows.IMenuCommandManager")
        [SatisfiedBy] ****.Modularity.Windows.Commanding.MenuCommandManager (ContractName="****.Modularity.Windows.IMenuCommandManager") from: ****.Modularity.Windows.Commanding.MenuCommandManager from: AssemblyCatalog (Assembly="****.Modularity.Windows, Version=2.4.0.347, Culture=neutral, PublicKeyToken=null")

    [Part] ****.Modularity.Windows.Navigation.NavigationManager from: AssemblyCatalog (Assembly="****.Modularity.Windows, Version=2.4.0.347, Culture=neutral, PublicKeyToken=null")
      [Export] ****.Modularity.Windows.Navigation.NavigationManager (ContractName="****.Framework.ViewModel.INavigationService")
      [Export] ****.Modularity.Windows.Navigation.NavigationManager (ContractName="****.Modularity.Windows.Navigation.INavigationManager")
      [Import] ****.Modularity.Windows.Navigation.NavigationManager..ctor (Parameter="moduleManager", ContractName="****.Modularity.Modules.IModuleManager")
        [SatisfiedBy] ****.Modularity.Modules.ModuleManager (ContractName="****.Modularity.Modules.IModuleManager") from: ****.Modularity.Modules.ModuleManager from: AssemblyCatalog (Assembly="****.Modularity.Mef, Version=2.4.0.347, Culture=neutral, PublicKeyToken=null")

    [Part] Logging.Module.LogConfigurationModuleRoot from: AssemblyCatalog (Assembly="Logging.Module, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")
      [Export] Logging.Module.LogConfigurationModuleRoot (ContractName="****.Modularity.IModule")
      [Import] Logging.Module.LogConfigurationModuleRoot..ctor (Parameter="logConfiguration", ContractName="Logging.ViewModel.Interfaces.ILogConfiguration")
        [SatisfiedBy] Logging.ViewModel.LogConfigurationViewModel (ContractName="Logging.ViewModel.Interfaces.ILogConfiguration") from: Logging.ViewModel.LogConfigurationViewModel from: AssemblyCatalog (Assembly="Logging.ViewModel, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")

    [Part] Logging.Module.LogViewModuleRoot from: AssemblyCatalog (Assembly="Logging.Module, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")
      [Export] Logging.Module.LogViewModuleRoot (ContractName="****.Modularity.IModule")
      [Import] Logging.Module.LogViewModuleRoot..ctor (Parameter="navigationCommandManager", ContractName="****.Modularity.Windows.Commanding.INavigationCommandManager")
        [SatisfiedBy] ****.Modularity.Windows.Commanding.INavigationCommandManager
        [Unsuitable] ****.Modularity.Windows.Commanding.NavigationCommandManager (ContractName="****.Modularity.Windows.Commanding.INavigationCommandManager") from: ****.Modularity.Windows.Commanding.NavigationCommandManager from: AssemblyCatalog (Assembly="****.Modularity.Windows, Version=2.4.0.347, Culture=neutral, PublicKeyToken=null")
      [Import] Logging.Module.LogViewModuleRoot..ctor (Parameter="settingsManager", ContractName="****.Modularity.ISettingsManager")
        [SatisfiedBy] ****.Modularity.ISettingsManager
      [Import] Logging.Module.LogViewModuleRoot..ctor (Parameter="busyService", ContractName="****.Modularity.Windows.IBusyService")
        [SatisfiedBy] ****.Modularity.Shells.ViewModel.ShellViewModel (ContractName="****.Modularity.Windows.IBusyService") from: ****.Modularity.Shells.ViewModel.ShellViewModel from: AssemblyCatalog (Assembly="****.Modularity.Shells, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")

    [Part] Logging.ViewModel.LogConfigurationViewModel from: AssemblyCatalog (Assembly="Logging.ViewModel, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")
      [Export] Logging.ViewModel.LogConfigurationViewModel (ContractName="Logging.ViewModel.Interfaces.ILogConfiguration")
      [Import] Logging.ViewModel.LogConfigurationViewModel..ctor (Parameter="viewModelManager", ContractName="****.Framework.ViewModel.ViewModelManager")
    [SatisfiedBy] ****.Framework.ViewModel.ViewModelManager

      [Import] Logging.ViewModel.LogConfigurationViewModel..ctor (Parameter="settingsManager", ContractName="****.Modularity.ISettingsManager")
        [SatisfiedBy] ****.Modularity.ISettingsManager
      [Import] Logging.ViewModel.LogConfigurationViewModel..ctor (Parameter="busyService", ContractName="****.Modularity.Windows.IBusyService")
        [SatisfiedBy] ****.Modularity.Shells.ViewModel.ShellViewModel (ContractName="****.Modularity.Windows.IBusyService") from: ****.Modularity.Shells.ViewModel.ShellViewModel from: AssemblyCatalog (Assembly="****.Modularity.Shells, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")
      [Import] Logging.ViewModel.LogConfigurationViewModel..ctor (Parameter="actionExecuter", ContractName="****.Modularity.IActionExecuter")
        [SatisfiedBy] ****.Modularity.IActionExecuter

    [Part] Debug.Module.ModuleRoot from: AssemblyCatalog (Assembly="Debug.Module, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")
      [Export] Debug.Module.ModuleRoot (ContractName="****.Modularity.IModule")
      [Import] Debug.Module.ModuleRoot..ctor (Parameter="container", ContractName="System.ComponentModel.Composition.Hosting.CompositionContainer")
        [SatisfiedBy] System.ComponentModel.Composition.Hosting.CompositionContainer
      [Import] Debug.Module.ModuleRoot..ctor (Parameter="catalogs", ContractName="System.ComponentModel.Composition.Primitives.ComposablePartCatalog")
        [SatisfiedBy] System.ComponentModel.Composition.Primitives.ComposablePartCatalog
      [Import] Debug.Module.ModuleRoot..ctor (Parameter="shell", ContractName="****.Modularity.Windows.Shell.IShellDataContext")
        [SatisfiedBy] ****.Modularity.Shells.ViewModel.ShellViewModel (ContractName="****.Modularity.Windows.Shell.IShellDataContext") from: ****.Modularity.Shells.ViewModel.ShellViewModel from: AssemblyCatalog (Assembly="****.Modularity.Shells, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")
      [Import] Debug.Module.ModuleRoot..ctor (Parameter="settingsManager", ContractName="****.Modularity.ISettingsManager")
        [SatisfiedBy] ****.Modularity.ISettingsManager

1 个答案:

答案 0 :(得分:2)

由于ShellViewModel导出IBusyService和LogViewModuleRoot导入IBusyService

您确实有一个预导出(即构造函数导入)周期:

ShellViewModel - > IModuleManager - > IModule(s) - > LogViewModuleRoot

AllowDefault = true允许该循环中断,并且它不为null的原因是由于这些循环的构造顺序。它不是确定性的,如果你首先拉动LogViewModuleRoot对象,在另一种情况下很可能是null。

打破循环并确保始终设置的最佳方法可能是将IBusyService切换到LogViewModuleRoot上的属性导入。