我们来看一下CAB的默认moduleloader :
模块装载的时候Load方法会先检查一下传进来的参数有没有null值这些问题, 然后转而调用到上面的这个 InnerLoad方法来装载模块。这个方法依次的 装载服务、 初始化模块、 初始化workitem extension、 然后触发模块装载完毕事件....
起初我怀疑我的workitemextension 挂钩到workitem里面的时机晚了, 果然不出我所料。 我们看一下 ModuleMetaData 类的 InitializeModuleClasses 方法
看来要自己找方法解决了。那个NotifyOfLoadedModule 是最后的步骤, 这个步骤会触发 ModuleLoader.Loaded 事件。 这才是真正的装载完毕! 于是我改为在 ModuleLoaded 的loaded 事件发生的时候开始我写的逻辑。
贴一下我写的代码:
至此还没有结束,虽然那我的问题解决了, 但是我还是想到网上别人有什么更好的解决方法。 然后我找到了一篇文章有关新的 new module loader for CAB, 此模块装载器修正了我所说的这个bug, 还提供了一些很有用的新功能:
Towards the end of the Smart Client Software Factory project, we wanted to be able to support a more comprehensive module loader system for CAB applications. Our goals were:
1. Support grouping modules together into logical "sections" which represented groups of functionality. These groups might be things like "layout", "services", "applications", etc.2. Allow dependencies to be expressed between these sections (i.e., make sure you load all the layout modules before you load the application modules).
3. Allow dependencies to be expressed in an external place instead of forcing them to be expressed in attributes on the assembly.
4. Make it easier to provide transports for the profile catalog XML without having to write an entirely new enumerator.
5. If possible, preserve backward compatibility with the new loader and old enumerators, so that we could preserve effort people had putting into writing their own enumerators.
6. Fix a bug in the module loader that causes WorkItem extensions to be registered too late to see WorkItems that were being created in the module's Load method.
2. 允许表达 section 之间的关系依赖性(耦合), 比如你可以确定 排版section 会在 应用section 装载完毕之后再装载。
3. 允许在外部定义 关系依赖性,突破原先的只能在assembly attribute里面定义的局限。
4. 不需要写整个 模块枚举器来实现 profile catalog XML 的传输。
5. 向后兼容, 可以使用之前写好的 模块枚举器。
6. 修正了我上面所描述的那个bug, 这个bug 使得 WorkItem extension 注册晚了 ( 注册聆听workitem的RunStarted, Initialized等事件晚了 )。