Module MEF子容器模块未初始化

Module MEF子容器模块未初始化,module,prism,mef,containers,hierarchy,Module,Prism,Mef,Containers,Hierarchy,我有一个简单的容器层次结构,父容器使用目录目录在Shell MEFBootstrapper中定义,子容器使用不同的目录从父容器中创建 我的子容器也使用DirectoryCatalog(与父容器不同的路径),我可以看到容器在运行时具有部件和零件信息 但是,永远不会调用位于子容器中的模块的Initialize()方法 我的目标是使用子容器作为会话构造,允许用户创建新会话并在它们之间切换。但是如果我不能让组成模块初始化(并将它们的视图放到区域中),我就有点卡住了 我曾想过使用事件聚合器从会话管理器中引

我有一个简单的容器层次结构,父容器使用目录目录在Shell MEFBootstrapper中定义,子容器使用不同的目录从父容器中创建

我的子容器也使用DirectoryCatalog(与父容器不同的路径),我可以看到容器在运行时具有部件和零件信息

但是,永远不会调用位于子容器中的模块的Initialize()方法

我的目标是使用子容器作为会话构造,允许用户创建新会话并在它们之间切换。但是如果我不能让组成模块初始化(并将它们的视图放到区域中),我就有点卡住了

我曾想过使用事件聚合器从会话管理器中引发一个事件,以允许模块侦听事件并进行自我初始化,但这似乎也不起作用

一,。为什么不在加载到子容器中的模块上调用Initialize 二,。如何从容器实例“触发”初始化(在模块上下文之外)?您能否迭代容器中的程序集并以这种方式触发初始化

[来自壳牌项目中的MefBootstrapper]

    protected override DependencyObject CreateShell()
    {
        ExportProvider ep = this.Container as ExportProvider;
        this.Container.ComposeExportedValue(ep);
[来自管理我的会话(容器)的服务]

[新会话(容器)的构造函数]

=====

被要求包含未调用其initialize方法的模块代码(尽管已加载到有问题的容器中…我甚至可以延迟实例化模块,但调用initialize()直接导致方法本身的注入操作失败)

namespace Module1
{
//, InitializationMode = InitializationMode.OnDemand
[ModuleExport("Module1.ModuleInit", typeof(Module1.ModuleInit))]
public class ModuleInit : IModule
{
    private readonly IRegionManager _regionManager;
    public IServiceLocator _serviceLocator;

    [ImportingConstructor]
    public ModuleInit(IRegionManager regionManager, IServiceLocator serviceLocator)
    {
        _regionManager = regionManager;
        _serviceLocator = serviceLocator;
    }

    #region IModule Members


    public void Initialize()
    {
        // Use View Discovery to automatically display the MasterView when the TopLeft region is displayed.
        _regionManager.RegisterViewWithRegion(RegionNames.TopLeftRegion, () => _serviceLocator.GetInstance<MasterView>());
    }

    #endregion
}
名称空间模块1
{
//,InitializationMode=InitializationMode.OnDemand
[ModuleExport(“Module1.ModuleInit”,typeof(Module1.ModuleInit))]
公共类模块单元:IModule
{
私有只读IRegionManager _regionManager;
公共IServiceLocator\u服务定位器;
[导入构造函数]
公共模块单元(IRegionManager regionManager、IServiceLocator serviceLocator)
{
_regionManager=regionManager;
_serviceLocator=serviceLocator;
}
#区域模块成员
公共无效初始化()
{
//显示左上角区域时,使用视图发现自动显示主视图。
_regionManager.RegisterViewWithRegion(RegionNames.TopLeftRegion,()=>\u serviceLocator.GetInstance());
}
#端区
}

}

我已经多次遇到这个问题,解决它非常简单

从模块中删除构造函数。Prism模块的激活方式与经典导出类型不同,因此模块无法使用ImportingConstructor导入所需的服务。请使用Initialize方法中的ServiceLocator初始化它们

这将有助于:

[ModuleExport("Module1.ModuleInit", typeof(Module1.ModuleInit))]
public class ModuleInit : IModule
{
    private readonly IRegionManager _regionManager;

    public void Initialize()
    {
        _regionManager = ServiceLocator.Current.GetInstance<IRegionManager>();

        _regionManager.RegisterViewWithRegion(RegionNames.TopLeftRegion, () => _serviceLocator.GetInstance<MasterView>());
    }
}
[ModuleExport(“Module1.ModuleInit”,typeof(Module1.ModuleInit))]
公共类模块单元:IModule
{
私有只读IRegionManager _regionManager;
公共无效初始化()
{
_regionManager=ServiceLocator.Current.GetInstance();
_regionManager.RegisterViewWithRegion(RegionNames.TopLeftRegion,()=>\u serviceLocator.GetInstance());
}
}

我还认为这种行为有点令人不安。

我下载了您的代码并查看了它。我立即发现了问题。由于目录目录如下,引导程序实际上正在获得导出:

DirectoryCatalog catalog = new DirectoryCatalog(".");
this.AggregateCatalog.Catalogs.Add(catalog);
这意味着您将从此目录中的程序集获取导出。因此,您只需复制目录“”中具有导出类型的所有程序集,即执行目录(Debug/bin)

只需复制bin目录中的Module1和Module2,所有内容都将优雅地组合:)

实际上,我发现应该复制bin目录中的模块的构建后事件不起作用。也许是因为你的名字更名了。因此,如果您希望它在生成后自动复制程序集,只需将实际的生成后事件替换为以下事件:

copy "$(TargetDir)\$(TargetFileName)" "$(TargetDir)\..\..\..\Shell\bin\$(ConfigurationName)\"

我的modules Initialize()方法没有被调用时也遇到了同样的问题。。。我意识到我在Initialize方法上省略了“override”关键字,该方法在我所有模块继承自的模块基类中声明为virtual。。。添加了“覆盖”,它成功了

你能展示一个带有
Initialize
方法的示例模块吗?当然,非常简单,直接来自VS2010中的PRISM模板项目:(参见编辑)谢谢你的建议,但是即使有了这些更改,Initialize方法也不会被调用。在MefBootTrapper之外创建(子)容器时,如果没有调用ConfigureContainer方法,该容器目录中的模块如何初始化?我知道我遗漏了一些很明显的东西。你说的“创造”是什么意思?它是在一个容器中组成的还是只是实例化的?我写了关于子容器的created。它们是使用以下内容创建的:this.appHost=new CompositionContainer(catalog,new ExportProvider[]{provider});如果要从引导程序初始化此模块,请重写ConfigureAggregate方法并调用this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(InitModule.Assembly));如果程序集位于目录中,请改用DirectoryCatalog。如果要在Booostrapper之外初始化模块,请调用ServiceLocator.Current.GetInstance()来组合模块。但是,如果这个问题无法解决,您能否提供一个示例项目,这样我就可以重现您的问题并在这方面为您提供帮助?链接到示例的zip:查看您是否可以让第一个会话实例的容器实际加载模块1和模块2并显示它们。再次感谢您花时间查看此内容。但是,如果我将Module1和Module2放入根目录,它们将
DirectoryCatalog catalog = new DirectoryCatalog(".");
this.AggregateCatalog.Catalogs.Add(catalog);
copy "$(TargetDir)\$(TargetFileName)" "$(TargetDir)\..\..\..\Shell\bin\$(ConfigurationName)\"