Я нахожусь в процессе разработки системы, которая позволит мне представлять широкомасштабные задачи в виде рабочих процессов, которые представляют свои рабочие элементы с помощью метода 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 #, который его поддерживает, я могу составлять эти рабочие процессы - например, рабочие процессы более высокого уровня, которые потребляют и управляют вспомогательными процессами. Например, я написал простой рабочий процесс, который просто чередует два дочерних рабочих процесса.
У меня такой вопрос - выглядит ли подобная архитектура разумной, особенно с точки зрения ремонтопригодности? Похоже, что для меня достигнуто несколько целей - самодокументируемый код (рабочий процесс читает процедурно, поэтому я знаю, что будет выполняться на каких этапах), разделение задач (поиск предметов с низким запасом не зависит от отправки электронной почты на склад) и т.д. Кроме того, есть ли потенциальные проблемы с такой архитектурой, которую я не вижу? Наконец, пробовали ли вы это раньше - я просто заново открываю это?