私は、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() メソッドが呼び出されます。Workflow() を列挙し、ワークアイテムの前後のイベントをラップし、イベント間で Execute を呼び出す WorkflowRunner クラスがあります。これにより、消費するアプリケーションは、キャンセル、作業項目のプロパティの変更など、作業項目の前後に必要なことを何でも行うことができます。
これらすべての利点は、タスクのコア ロジックを、作業を完了するための作業項目の観点から表現できることであり、かなり単純でほぼ手続き的な方法でそれを実行できることです。また、IEnumerable と、それをサポートする C# のシンタックス シュガーを使用しているため、サブワークフローを使用して操作する高レベルのワークフローのように、これらのワークフローを作成できます。たとえば、2 つの子ワークフローをインターリーブするだけの単純なワークフローを作成しました。
私の質問はこれです - 特に保守性の観点から、この種のアーキテクチャは合理的に見えますか? 私にとっていくつかの目標を達成しているようです-自己文書化コード(ワークフローは手続き的に読み取られるため、どのステップで何が実行されるかがわかります)、懸念の分離(在庫の少ないアイテムを見つけることは、倉庫に電子メールを送信することに依存しません)、など。また、この種のアーキテクチャには、私が見ていない潜在的な問題はありますか? 最後に、これは以前に試されたことがありますか?これを再発見しただけですか?