如何在模块中使用模块
How to use modules in modules
我想要一个可以在隔离环境中开发的模块,但仍然是一个可以插入另一个项目的模块。
想法:目前我有状态机驱动的模块化项目,其中每个模块都由 DSL 定义,因此主项目有其上下文和命令映射以及状态机。现在,其中一个模块将变成本质上相同的东西——它将拥有自己的上下文、自己的子模块和自己的 DSL 定义,这些定义将与主上下文分开。
- 这可能吗?
- 关于如何通过模块自动将事件从主上下文转发到模块上下文,是否有一些最佳实践?
- 有没有办法将模块私有调度程序映射为独立上下文的调度程序?
- 好像完全可以
- 由于我没有找到关于此用例的任何文档或示例,我认为没有最佳实践
- 据我所知,可以创建自己的应用程序上下文 class,这将有可能覆盖上下文调度程序。但它不会解决太多问题,因为命令触发器只能监听模块而不能监听整个上下文
所以我假设解决这个问题的最好方法是创建一个单独的通信模块,它将映射到 "child" DSL 中,然后 "parent" 模块将通过核心工厂定位它"child assembler" 并通过它触发事件。它还使通信更易于测试,因为这将通过一个可以轻松 tested/mocked/observed 的单点引导整个通信,并且它还抽象了 "parent" 应用程序
的实现和事件
HexMachina 只支持一个context by applications(以后应该支持parent-child context)。我不确定你到底想要什么,但让我们从几件事开始。
模块之间的通信。
模块有两个调度程序,一个内部用于与 FrontController 的所有内部通信,另一个 public 用于所有外部通信。
要在模块之间进行通信,一个模块必须订阅另一个模块。在 DSL 中,它是这样定义的:
<chat id="chat" type="hex.ioc.parser.xml.mock.MockChatModule">
<listen ref="translation"/>
</chat>
<translation id="translation" type="hex.ioc.parser.xml.mock.MockTranslationModule">
<listen ref="chat">
<event static-ref="hex.ioc.parser.xml.mock.MockChatModule.TEXT_INPUT" method="onSomethingToTranslate"/>
</listen>
</translation>
本例中,当聊天模块dispatchPublicMessage(MockChatModule.TEXT_INPUT, [“data”])
时,翻译模块的onSomethingToTranslate(textToTranslate : String)
方法被执行。
在许多文件中拆分 DSL
您可以使用上下文包含和条件属性按“组件”组织您的 DSL 文件,并定义您要在编译时使用的内容。
<root name="applicationContext">
<include if=“useModuleA” file="context/ModuleA.xml"/>
</root>
条件属性值由编译器标志定义 (-D useModuleA=1
) 或直接在代码中检查此 link。
用状态机驱动很多模块
如果你想在一个状态变化时驱动多个模块,你已经使用命令来管理它。
<state id="assemblingEnd" ref="applicationContext.state.ASSEMBLING_END">
<enter command-class="hex.ioc.parser.xml.assembler.mock.MockStateCommand" fire-once="true"/>
</state>
希望对您有所帮助。如果您需要更多详细信息,请告诉我。
我想要一个可以在隔离环境中开发的模块,但仍然是一个可以插入另一个项目的模块。
想法:目前我有状态机驱动的模块化项目,其中每个模块都由 DSL 定义,因此主项目有其上下文和命令映射以及状态机。现在,其中一个模块将变成本质上相同的东西——它将拥有自己的上下文、自己的子模块和自己的 DSL 定义,这些定义将与主上下文分开。
- 这可能吗?
- 关于如何通过模块自动将事件从主上下文转发到模块上下文,是否有一些最佳实践?
- 有没有办法将模块私有调度程序映射为独立上下文的调度程序?
- 好像完全可以
- 由于我没有找到关于此用例的任何文档或示例,我认为没有最佳实践
- 据我所知,可以创建自己的应用程序上下文 class,这将有可能覆盖上下文调度程序。但它不会解决太多问题,因为命令触发器只能监听模块而不能监听整个上下文
所以我假设解决这个问题的最好方法是创建一个单独的通信模块,它将映射到 "child" DSL 中,然后 "parent" 模块将通过核心工厂定位它"child assembler" 并通过它触发事件。它还使通信更易于测试,因为这将通过一个可以轻松 tested/mocked/observed 的单点引导整个通信,并且它还抽象了 "parent" 应用程序
的实现和事件HexMachina 只支持一个context by applications(以后应该支持parent-child context)。我不确定你到底想要什么,但让我们从几件事开始。
模块之间的通信。
模块有两个调度程序,一个内部用于与 FrontController 的所有内部通信,另一个 public 用于所有外部通信。 要在模块之间进行通信,一个模块必须订阅另一个模块。在 DSL 中,它是这样定义的:
<chat id="chat" type="hex.ioc.parser.xml.mock.MockChatModule">
<listen ref="translation"/>
</chat>
<translation id="translation" type="hex.ioc.parser.xml.mock.MockTranslationModule">
<listen ref="chat">
<event static-ref="hex.ioc.parser.xml.mock.MockChatModule.TEXT_INPUT" method="onSomethingToTranslate"/>
</listen>
</translation>
本例中,当聊天模块dispatchPublicMessage(MockChatModule.TEXT_INPUT, [“data”])
时,翻译模块的onSomethingToTranslate(textToTranslate : String)
方法被执行。
在许多文件中拆分 DSL
您可以使用上下文包含和条件属性按“组件”组织您的 DSL 文件,并定义您要在编译时使用的内容。
<root name="applicationContext">
<include if=“useModuleA” file="context/ModuleA.xml"/>
</root>
条件属性值由编译器标志定义 (-D useModuleA=1
) 或直接在代码中检查此 link。
用状态机驱动很多模块
如果你想在一个状态变化时驱动多个模块,你已经使用命令来管理它。
<state id="assemblingEnd" ref="applicationContext.state.ASSEMBLING_END">
<enter command-class="hex.ioc.parser.xml.assembler.mock.MockStateCommand" fire-once="true"/>
</state>
希望对您有所帮助。如果您需要更多详细信息,请告诉我。