private static async Task ReCalcInternalAsync( this Report report, DateTime timestampUtc, IReadOnlyCollection <Func <IProtocolFactory, IProtocolFactory> > protocolFactoryFuncs = null, IReadOnlyCollection <Type> additionalTypesForCoreCellOps = null) { // NOTE: THIS CODE IS A NEAR DUPLICATE OF THE SYNC METHOD ABOVE; NO GOOD WAY TO D.R.Y. IT OUT var recalcPhase = RecalcPhase.Unknown; // ReSharper disable once AccessToModifiedClosure RecalcPhase GetRecalcPhaseFunc() => recalcPhase; var reportCache = new ReportCache(report); var protocolFactory = reportCache.BuildProtocolFactoryToExecuteAllOperations(timestampUtc, protocolFactoryFuncs, additionalTypesForCoreCellOps, GetRecalcPhaseFunc); reportCache.ClearCells(timestampUtc); recalcPhase = RecalcPhase.CellOpExecution; foreach (var cell in reportCache.OperationCells) { var executeOperationCellIfNecessaryOp = cell.BuildExecuteOperationCellIfNecessaryOp(); await protocolFactory.GetProtocolAndExecuteViaReflectionAsync(executeOperationCellIfNecessaryOp); } recalcPhase = RecalcPhase.Validation; foreach (var cell in reportCache.ValidationCells) { var validateCellIfNecessaryOp = new ValidateCellIfNecessaryOp(cell); await protocolFactory.GetProtocolAndExecuteViaReflectionAsync(validateCellIfNecessaryOp); } recalcPhase = RecalcPhase.AvailabilityCheck; foreach (var cell in reportCache.AvailabilityCheckCells) { var checkAvailabilityOfCellIfNecessaryOp = new CheckAvailabilityOfCellIfNecessaryOp(cell); await protocolFactory.GetProtocolAndExecuteViaReflectionAsync(checkAvailabilityOfCellIfNecessaryOp); } if (reportCache.PrepareToRerunRecalc(timestampUtc)) { await report.ReCalcInternalAsync(timestampUtc, protocolFactoryFuncs, additionalTypesForCoreCellOps); } }
private async Task <IValidationCell> GetCellAndValidateIfNecessaryAsync( IReturningOperation <CellLocatorBase> cellLocatorOp) { // NOTE: THIS CODE IS A NEAR DUPLICATE OF THE SYNC METHOD ABOVE; NO GOOD WAY TO D.R.Y. IT OUT var cellLocator = await this.protocolFactory.GetProtocolAndExecuteViaReflectionAsync <CellLocatorBase>(cellLocatorOp); var cell = this.GetCell(cellLocator); if (!(cell is IValidationCell result)) { throw new CellNotFoundException(Invariant($"The operation addresses a cell whose type is not an {typeof(IValidationCell).ToStringReadable()}: {cell.GetType().ToStringReadable()}."), cellLocator); } var validateCellIfNecessaryOp = new ValidateCellIfNecessaryOp(result); await this.protocolFactory.GetProtocolAndExecuteViaReflectionAsync(validateCellIfNecessaryOp); return(result); }
/// <inheritdoc /> public async Task ExecuteAsync( ValidateCellIfNecessaryOp operation) { // NOTE: THIS CODE IS A NEAR DUPLICATE OF THE SYNC METHOD ABOVE; NO GOOD WAY TO D.R.Y. IT OUT if (operation == null) { throw new ArgumentNullException(nameof(operation)); } var cell = operation.Cell; try { DataStructureCellProtocols.CurrentCellStack.Push(cell); await this.ValidateCellIfNecessaryAsync(cell); } finally { var poppedCell = DataStructureCellProtocols.CurrentCellStack.Pop(); DataStructureCellProtocols.ThrowIfUnexpectedCellPoppedOffCurrentCellStack(cell, poppedCell); } }