Files
Sharepoint-Toolbox/SharepointToolbox/Services/BulkOperationRunner.cs
Dev 39deed9d8d feat(04-01): add Phase 4 models, interfaces, BulkOperationRunner, and test scaffolds
- Install CsvHelper 33.1.0 and Microsoft.Graph 5.74.0 (main + test projects)
- Add 14 core model/enum files (BulkOperationResult, BulkMemberRow, BulkSiteRow, TransferJob, FolderStructureRow, SiteTemplate, SiteTemplateOptions, TemplateLibraryInfo, TemplateFolderInfo, TemplatePermissionGroup, ConflictPolicy, TransferMode, CsvValidationRow)
- Add 6 service interfaces (IFileTransferService, IBulkMemberService, IBulkSiteService, ITemplateService, IFolderStructureService, ICsvValidationService)
- Add BulkOperationRunner with continue-on-error and cancellation support
- Add BulkResultCsvExportService stub (compile-ready)
- Add test scaffolds: BulkOperationRunnerTests (5 passing), BulkResultCsvExportServiceTests (2 passing), CsvValidationServiceTests (6 skipped), TemplateRepositoryTests (4 skipped)
2026-04-03 09:53:05 +02:00

37 lines
1.4 KiB
C#

using SharepointToolbox.Core.Models;
namespace SharepointToolbox.Services;
public static class BulkOperationRunner
{
/// <summary>
/// Runs a bulk operation with continue-on-error semantics, per-item result tracking,
/// and cancellation support. OperationCanceledException propagates immediately.
/// </summary>
public static async Task<BulkOperationSummary<TItem>> RunAsync<TItem>(
IReadOnlyList<TItem> items,
Func<TItem, int, CancellationToken, Task> processItem,
IProgress<OperationProgress> progress,
CancellationToken ct)
{
var results = new List<BulkItemResult<TItem>>();
for (int i = 0; i < items.Count; i++)
{
ct.ThrowIfCancellationRequested();
progress.Report(new OperationProgress(i + 1, items.Count, $"Processing {i + 1}/{items.Count}..."));
try
{
await processItem(items[i], i, ct);
results.Add(BulkItemResult<TItem>.Success(items[i]));
}
catch (OperationCanceledException) { throw; }
catch (Exception ex)
{
results.Add(BulkItemResult<TItem>.Failed(items[i], ex.Message));
}
}
progress.Report(new OperationProgress(items.Count, items.Count, "Complete."));
return new BulkOperationSummary<TItem>(results);
}
}