[英]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.