我正在设计一个系统,该系统允许我将广泛的任务表示为工作流,通过 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# 语法糖,所以我可以组合这些工作流——比如使用和操作子工作流的更高级别的工作流。例如,我编写了一个简单的工作流程,它只是将两个子工作流程交错在一起。
我的问题是——这种架构看起来合理吗,尤其是从可维护性的角度来看?它似乎实现了我的几个目标 - 自我记录代码(工作流程按程序读取,所以我知道将在哪些步骤中执行什么),关注点分离(查找低库存项目不依赖于向仓库发送电子邮件),等等 - 这种架构是否存在我没有看到的任何潜在问题?最后,这之前有没有尝试过——我只是重新发现了这个吗?