我正在设计一个允许我将宽范围任务表示为工作流的系统,它通过IEnumerable方法公开他们的工作项。这里的目的是使用C#的'yield'机制来允许我编写工作流程执行系统可以按其认为合适执行的伪程序代码。
例如,假设我的工作流程包括在数据库上运行查询并在查询返回特定结果时发送电子邮件警报。这可能是工作流程:
public override IEnumerable<WorkItem> Workflow() {
// These would probably be injected from elsewhere
var db = new DB();
var emailServer = new EmailServer();
// other workitems here
var ci = new FindLowInventoryItems(db);
yield return ci;
if (ci.LowInventoryItems.Any()) {
var email = new SendEmailToWarehouse("Inventory is low.", ci.LowInventoryItems);
yield return email;
}
// other workitems here
}
CheckInventory和EmailWarehouse是派生自WorkItem的对象,它具有子类实现的抽象Execute()方法,封装了这些操作的行为。在工作流框架中调用Execute()方法 - 我有一个WorkflowRunner类,它枚举Workflow(),包围工作项的事件前和事件后,并在事件之间调用Execute。这允许消费应用程序在工作项之前或之后执行它所需的任何操作,包括取消,更改工作项属性等。
我认为,所有这些的好处在于,我可以根据负责完成工作的工作项来表达任务的核心逻辑,我可以用相当简单,几乎是程序的方式来完成。另外,因为我使用IEnumerable和C#支持它的语法糖,我可以组合这些工作流程 - 比如使用和操作子工作流程的更高级别的工作流程。例如,我编写了一个简单的工作流程,只将两个子工作流交错在一起。
我的问题是 - 这种架构看起来是否合理,特别是从可维护性的角度来看?它似乎为我实现了几个目标 - 自我记录代码(工作流程从程序上读取,所以我知道将在什么步骤中执行什么),关注点分离(找到低库存项目不依赖于向仓库发送电子邮件),此外 - 这种架构是否存在任何潜在问题,我没有看到?最后,这是否曾经尝试过 - 我只是重新发现了这个?
答案 0 :(得分:2)
就个人而言,这对我来说是一个“建造前购买”的决定。在我写之前我会先买点东西。
我为一家公司工作,这家公司规模相当大,而且钱很愚蠢,所以如果你自己写这篇文章并且买不到东西,我会撤回评论。
以下是一些随意的想法:
我将工作流外部化为我可以在启动时读取的配置,可能来自文件或数据库。
它看起来像有状态机,状态,转换,事件和动作。
我希望能够插入不同的动作,以便我可以动态定制不同的流程。
我希望能够注册想要在特定事件发生时得到通知的不同订阅者。
我不希望看到任何硬编码的电子邮件服务器。我宁愿将其封装到一个EmailNotifier中,我可以将其插入需要它的事件中。蜂鸣器通知怎么样?还是一部手机?黑莓?相同的架构,不同的通知。
您想要包含人工互动的处理程序吗?我处理的所有工作流程都是人工和自动处理的混合。
您是否希望连接到其他系统,例如数据库,其他应用程序,Web服务?
这是一个棘手的问题。祝你好运。
答案 1 :(得分:0)
工作流程支持现在是.Net框架的一部分,名为“Workflow Foundation(WF)”。学习如何使用内置库几乎肯定比编写自己的库更容易,正如duffymo在他的“在构建前购买”评论中指出的那样。
工作流以XAML表示,并由Visual Studio中的设计人员支持。 有三种类型的工作流程(来自维基百科,下面的链接)
- 顺序工作流程(通常为流程 以图表为基础,从一个阶段发展 到下一步,不退一步)
- 的国家 机器工作流程(来自 '州'到'州',这些工作流程 更复杂,回归 前一点,如果需要)
- 规则驱动的工作流程(已实施 基于Sequential / StateMachine 流程。规则决定了 工作流程的进展)