对简单的动态工作流系统进行建模(通过数据驱动的依赖注入?

本文关键字:数据驱动 注入 依赖 动态 简单 工作流 系统 建模 | 更新日期: 2023-09-27 18:36:31

这更像是一个架构问题,而不是对代码帮助的请求。我想我想出了几个解决方案,但其中一些感觉很奇怪。因此,我正在寻找任何类型的输入。

问题所在

请记住,以下情况纯粹是假设的,旨在以简单的方式说明情况。

假设我有一个非常简单的工作流系统,我希望通过XML文件进行配置。为了使我们的假设示例保持简单,我们将此工作流系统称为具有任意数量步骤的"向导"。可以有三个可能的步骤,但它们可以按任意顺序重复任意次数。

假设三个可能的向导步骤是:

  • 信息屏幕
  • 是/否选项屏幕
  • 选择路径屏幕

这三个屏幕将对应于三个类,它们都继承自一个公共接口。我们将这些定义如下:

public interface IWizardScreen {
    void Show();
}
public class InformationScreen : IWizardScreen, IDisposable {
    // Implementation
}
public class YesNoChoiceScreen : IWizardScreen, IDisposable {
    // Implementation
}
public class ChoosePathScreen : IWizardScreen, IDisposable {
    // Implementation
}

现在,我们的向导应用程序将使用这些类向最终用户显示一系列屏幕,这些屏幕存储在列表或队列中,如下所示:

public Queue<IWizardScreen> WorkflowScreens;

最后,这些向导屏幕序列(WorkflowScreens对象)的填充将由外部 XML 文件驱动,该文件可由管理员用户编辑。此 XML 文件可能如下所示:

<workflow>
    <information-screen>
        <text>My first screen</text>
    </information-screen>
    <information-screen>
        <text>My second screen</text>
    </information-screen>
    <yesno-choice-screen var="mychoice">
        <text>My choice screen</text>
        <yes>2</yes>
        <no>1</no>
    </yesno-choice-screen>
    <choosepath-screen show-if="mychoice = '2'" />
    <information-screen show-if="mychoice = '1'>
        <text>My third screen</text>
    </information-screen>
</workflow>

需要以某种方式处理此 XML 文件才能获得与以下相同的结果:

public Queue<IWizardScreen> WorkflowScreens = new Queue<IWizardScreen>({
    new InformationScreen("My first screen"),
    new InformationScreen("My second screen"),
    new YesNoChoiceScreen("mychoice", "My choice screen", 2, 1),
    new ChoosePathScreen() { showIf = "mychoice = '2'" },
    new InformationScreen("My third screen") { showIf = "mychoice = '1'" }
});

同样,确切的规范和构造函数无关紧要,因为这是一个纯粹的假设示例。最后,我需要的是将该 XML 文件转换为具有尽可能多的可扩展性的对象数组(理想情况下,理论上,管理员用户可以将具有新步骤的新 DLL 放入"bin"文件夹中并添加新标签,并获得一个如此简单的新屏幕)和尽可能少的过度设计。(为了澄清,前面括号中的示例也纯粹是作为示例,与此问题无关;特定功能不是必需的,但展示了我更喜欢的可扩展性程度)。

可能的解决方案 1:运行 XSLT 转换以馈送到 IoC 容器中

在这种情况下,这似乎是最自然的,但也感觉非常过度和奇怪。基本上,XML 文件将通过 XSLT 转换馈送,为 DI 容器(Castle、Spring.NET 等)创建一个 XML 配置文件,然后填充对象。

可能的解决方案 2:只需手动解析 XML

这个感觉最简单,但也最不可扩展和"笨拙",我需要自己创建大量样板代码(用于解析 XML、填充构造函数参数,甚至可能还有一些用于解决实际组件的自主开发 DI)。

潜在的解决方案3:询问堆栈溢出

我现在确定的那个:)

对简单的动态工作流系统进行建模(通过数据驱动的依赖注入?

作为第三个选项(我使用过很多次),为什么不直接在 IOC 容器中对工作流进行编码。像 spring.net 这样的东西具有使用它自己的 XML 指定向导配置等内容所需的一切。 这将为您提供与自己解析 xml 相同的结果,而无需重新发明轮子。