繁体   English   中英

MEF子容器模块未初始化

[英]MEF Child Container Module Not Initializing

我有一个简单的容器层次结构,其中的父容器是在Shell MEFBootstrapper中使用目录目录定义的,而子容器是通过具有不同目录的父容器创建的。

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

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

我的目标是将子容器用作会话构造,从而允许用户创建新会话并在它们之间切换。 但是,如果我无法让组成模块初始化(并将它们的视图放入区域中),那我就很困惑。

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

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

[来自Shell项目中的MefBootstrapper]

    protected override DependencyObject CreateShell()
    {
        ExportProvider ep = this.Container as ExportProvider;
        this.Container.ComposeExportedValue(ep);

[来自管理我的会话的服务(容器)]

    [ImportingConstructor]
    public SessionService(ExportProvider provider)
    {

[新会议的组织者(容器)]

    private void Init(ComposablePartCatalog catalog, ExportProvider provider, string name, int callId, bool useContextProxy)
    {
        this._Name = name;
        this._CallID = callId;
        this.startTime = DateTime.Now;
        this.appHost = new CompositionContainer(catalog, new ExportProvider[] { provider });
    }

=====

被要求包括未调用其初始化方法的模块代码(尽管正在将其加载到有问题的容器中……我什至可以懒惰地实例化该模块,但是调用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
}

}

我下载了您的代码并进行了查看。 我立即发现了问题。 像这样的DirectoryCatalog,引导程序实际上正在获得导出:

DirectoryCatalog catalog = new DirectoryCatalog(".");
this.AggregateCatalog.Catalogs.Add(catalog);

这意味着您将从该目录中的程序集中获取导出。 因此,您只需要将所有带有导出类型的程序集复制到目录“。”中,即执行目录(Debug / bin)。

只需将bin1和Module2复制到bin目录中,一切都会正常进行:)

实际上,我发现应该复制bin目录中的模块的构建后事件无法正常工作。 可能是因为您重命名了。 因此,如果您希望它在构建后自动复制程序集,只需用此事件替换实际的构建后事件:

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

我已经有很多次这个问题了,解决它真的很简单。

从模块中删除构造函数。 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>());
    }
}

我也认为这种行为令人不安。

我遇到了同样的问题,其中我的模块Initialize()方法没有被调用...我意识到我在我的所有模块都继承自的Module基类中的Virtualize初始化方法上取消了Initialize方法的“ override”关键字...添加了“替代”,它起作用了!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM