Feature: Storage Core Abstraction (ManagedCode.Storage.Core)
Purpose
Provide a single, provider-agnostic storage API for .NET so application code can upload/download/list/stream files without being coupled to vendor SDKs.
The core package defines:
IStorageand related capability interfaces (IUploader,IDownloader,IStreamer)- consistent
Result/Result<T>error handling - common option models (upload/download/delete/metadata/legal hold)
- provider factories (
IStorageProvider,IStorageFactory) and DI helpers
Main Flows
1) Upload / Download
flowchart LR
App[Application code] --> I[IStorage]
I --> B[BaseStorage<TClient, TOptions>]
B --> C[Provider storage client]
C --> SDK[Vendor SDK / API]
SDK --> B
B --> I
I --> App
2) Options-driven pathing + metadata
- Callers pass
UploadOptions/DownloadOptions/MetadataOptionsto control:FileName,Directory(logical path)MimeType(normalized throughMimeHelper)- per-provider metadata where supported
Components
Key files:
ManagedCode.Storage.Core/IStorage.cs— main abstraction surfaceManagedCode.Storage.Core/BaseStorage.cs— shared lifecycle + template methods for providersManagedCode.Storage.Core/Models/*.cs— option models andBlobMetadata/LocalFileManagedCode.Storage.Core/Helpers/Crc32Helper.cs— streamed CRC32 helpers used by chunked uploads/downloadsManagedCode.Storage.Core/Helpers/PathHelper.cs— shared path manipulation utilitiesManagedCode.Storage.Core/Providers/*— provider factory abstractions and the defaultStorageFactoryManagedCode.Storage.Core/Extensions/ServiceCollectionExtensions.cs— DI helpers
Current Behavior
- Provider implementations typically inherit
BaseStorage<TClient, TOptions>and only implement provider-specific operations. - Public operations return
Result/Result<T>with:IsSuccessand (when successful)Value- exceptions captured and returned as failed results
- MIME type lookups should flow through
MimeHelper(do not add ad-hoc MIME detection). StringStreamexposes the original UTF-16 code units as little-endian bytes. Byte positions can be odd or past the end of the stream. Attempts to move before the beginning fail and preserve the current position.VerifiedContentSnapshotchecks the declared length and SHA-256 before returning a file-backed snapshot. It reads at most one byte beyond the declared length to detect trailing content.LocalFile.FromStreamAsynccopies from a caller-owned stream and replaces the destination contents. On failure it closes the destination and removes a newly created file. Copies to an existing named destination write in place.- Downloads release their temporary destination when the provider reports failure or returns a file at a different path. A caller-supplied destination stays on disk.
Tests
Tests/ManagedCode.Storage.Tests/Core/Crc32HelperTests.csTests/ManagedCode.Storage.Tests/Core/LocalFileTests.csTests/ManagedCode.Storage.Tests/Core/StringStreamTests.csTests/ManagedCode.Storage.Tests/Core/StorageClientChunkTests.cs(core chunk behaviour used by clients)
References
README.md(package list + quickstart)docs/Testing/strategy.md(suite structure and rules)