В моем текущем проекте я использую классы, которые реализуют следующий интерфейс ITransaction
, показанный ниже. Это общий интерфейс для транзакции, которую можно отменить. У меня также есть класс TransactionSet
, который используется для попытки нескольких транзакций или наборов транзакций и в конечном итоге может использоваться для создания дерева транзакций.
Некоторые реализации ITransaction
сохраняют временные ссылки на экземпляры объектов или файлы, которые они могут использовать позже, если есть вызов Undo()
. Успешная транзакция может быть позже подтверждена, после чего Undo()
больше не разрешено, и, таким образом, больше нет необходимости во временных данных. В настоящее время я использую Dispose()
в качестве метода подтверждения для очистки любых временных ресурсов.
Однако теперь я хотел бы, чтобы мои транзакции также запускали события, чтобы уведомлять другие классы о том, что произошло. Я не хочу, чтобы события срабатывали, пока транзакция не будет подтверждена. Потому что я не хочу, чтобы транзакция запускала события несколько раз, будучи отмененной, а затем снова запущенной.
Поскольку я использую Dispose()
для подтверждения транзакции, есть ли что-то неправильное в том, чтобы также запускать из него эти события? Или было бы лучше иметь отдельный метод Confirm()
в моем интерфейсе, который запускает события в дополнение к Dispose()
, который очищает временные данные? Я не могу вспомнить ни одного случая, когда я хотел бы подтвердить, но не удалять транзакцию. И все же мне не совсем ясно, что я должен и не должен делать в пределах Dispose()
.
public enum TransactionStatus
{
NotRun, // the Transaction has not been run, or has been undoed back to the original state
Successful, ///the action has been run and was successful
Error //there was an attempt to run the action but it failed
}
/// <summary>
/// Generic transaction interface
/// </summary>
public interface ITransaction
{
TransactionStatus Status { get; }
/// <summary>
/// Attempts the transaction returns true if successful, false if failed.
/// If failed it is expected that everything will be returned to the original state.
/// Does nothing if status is already Successful
/// </summary>
/// <returns></returns>
bool Go();
/// <summary>
/// Reverts the transaction
/// Only does something if status is successful.
/// Should return status to NotRun
/// </summary>
void Undo();
/// <summary>
/// A message describing the cause of the error if Status == Error
/// Otherwise equal String.Empty
/// </summary>
string ErrorMessage { get; }
}