Skip to content

File Storage

The File Storage module provides a standard interface for file and blob operations. Swap implementations via DI (Azure Blob, S3, local filesystem).

Quick Start

using Deepstaging.Effects;
using Deepstaging.Storage;

[EffectsModule(typeof(IFileStore))]
public sealed partial class StorageEffects;

[Runtime]
[Uses(typeof(StorageEffects))]
public sealed partial class AppRuntime;

The generator produces Eff<RT, A> wrappers for all six operations on IFileStore.

Effect Interface

IFileStore

Method Returns Description
UploadAsync(key, content, contentType) Task<FileMetadata> Upload a file to storage
DownloadAsync(key) Task<Stream> Download a file as a stream
DeleteAsync(key) Task Delete a file
ExistsAsync(key) Task<bool> Check if a file exists
GetMetadataAsync(key) Task<FileMetadata?> Get file metadata
GetPresignedUrlAsync(key, expiry) Task<string> Generate a time-limited direct URL

FileMetadata

public record FileMetadata(
    string Key,
    string Filename,
    string ContentType,
    long Size,
    string? ETag,
    DateTimeOffset CreatedAt);

Usage

// Upload and generate a download link
from metadata in StorageEffects.FileStore.UploadAsync<AppRuntime>(
    "invoices/2024/inv-001.pdf", pdfStream, "application/pdf")
from url in StorageEffects.FileStore.GetPresignedUrlAsync<AppRuntime>(
    metadata.Key, TimeSpan.FromMinutes(15))
select new { metadata.Key, DownloadUrl = url };

Resilience

Apply resilience via a wrapper interface extending IFileStore:

public interface IResilientFileStore : IFileStore
{
    [Retry(MaxAttempts = 3)]
    [Timeout(30_000)]
    new Task<FileMetadata> UploadAsync(string key, Stream content, string contentType);
}

See the Effects module resilience section for details on [Retry], [Timeout], and [CircuitBreaker].

Pluggable Implementations

Register a concrete IFileStore implementation in DI. The effect module delegates to whichever implementation is registered:

// Azure Blob Storage
services.AddSingleton<IFileStore, AzureBlobFileStore>();

// Amazon S3
services.AddSingleton<IFileStore, S3FileStore>();

// Local filesystem (development)
services.AddSingleton<IFileStore, LocalFileStore>();