NextGenPowerToys.Storage.S3.Light
1.5.1
dotnet add package NextGenPowerToys.Storage.S3.Light --version 1.5.1
NuGet\Install-Package NextGenPowerToys.Storage.S3.Light -Version 1.5.1
<PackageReference Include="NextGenPowerToys.Storage.S3.Light" Version="1.5.1" />
<PackageVersion Include="NextGenPowerToys.Storage.S3.Light" Version="1.5.1" />
<PackageReference Include="NextGenPowerToys.Storage.S3.Light" />
paket add NextGenPowerToys.Storage.S3.Light --version 1.5.1
#r "nuget: NextGenPowerToys.Storage.S3.Light, 1.5.1"
#:package NextGenPowerToys.Storage.S3.Light@1.5.1
#addin nuget:?package=NextGenPowerToys.Storage.S3.Light&version=1.5.1
#tool nuget:?package=NextGenPowerToys.Storage.S3.Light&version=1.5.1
NextGen PowerToys Storage S3 Light
A lightweight, resilient S3 storage library for .NET 8 with advanced features including Polly resilience patterns, health checks, and comprehensive file management capabilities.
🚀 Features
- 🛡️ Resilient Operations - Built-in retry policies, circuit breakers, and timeout handling using Polly v8
- 📁 File Management - Upload, download, delete, and list files with metadata tracking
- 🔗 Pre-signed URLs - Generate secure, time-limited download URLs
- 🏥 Health Checks - Integrated health monitoring for S3 connectivity
- 📊 Structured Logging - Comprehensive logging with structured data
- ⚡ High Performance - Optimized for speed and reliability
- 🔧 Easy Configuration - Simple setup with appsettings.json or code configuration
- 🪣 S3 Compatible - Works with AWS S3, MinIO, and other S3-compatible storage
📦 Installation
Install the NuGet package:
dotnet add package NextGenPowerToys.Storage.S3.Light
Or via Package Manager Console:
Install-Package NextGenPowerToys.Storage.S3.Light
⚙️ Configuration
appsettings.json
{
"S3Storage": {
"AccessKeyId": "your-access-key",
"SecretAccessKey": "your-secret-key",
"ServiceUrl": "https://s3.amazonaws.com",
"DefaultBucketName": "my-bucket",
"Region": "us-east-1",
"ForcePathStyle": false,
"UseServerSideEncryption": true
},
"S3Resilience": {
"MaxRetryAttempts": 3,
"BaseDelaySeconds": 1,
"MaxDelaySeconds": 30,
"UseExponentialBackoff": true,
"CircuitBreakerFailureThreshold": 5,
"CircuitBreakerDurationSeconds": 30,
"RequestTimeoutSeconds": 60
}
}
Dependency Injection Setup
using NextGenPowerToys.Storage.S3.Light.Extensions;
// Configure services
services.AddS3Storage(configuration);
// Add health checks (optional)
services.AddHealthChecks()
.AddS3HealthCheck();
🎯 Usage
Basic File Operations
using NextGenPowerToys.Storage.S3.Light.Abstractions.Interfaces;
using NextGenPowerToys.Storage.S3.Light.Abstractions.DTOs;
public class FileService
{
private readonly IFileStorageService _storageService;
public FileService(IFileStorageService storageService)
{
_storageService = storageService;
}
// Upload a file
public async Task<string> UploadFileAsync(IFormFile file)
{
var request = new FileUploadRequest
{
File = file,
BucketName = "my-bucket",
Tags = "document,upload"
};
var response = await _storageService.UploadFileAsync(request);
return response.Id; // Returns the file name as ID
}
// Download a file
public async Task<byte[]> DownloadFileAsync(string fileName)
{
var response = await _storageService.DownloadFileAsync(fileName);
return response.Content;
}
// Get file metadata
public async Task<FileMetadata?> GetFileInfoAsync(string fileName)
{
return await _storageService.GetFileMetadataAsync(fileName);
}
// Generate download URL
public async Task<string> GetDownloadUrlAsync(string fileName)
{
return await _storageService.GenerateDownloadUrlAsync(fileName, 60);
}
// List all files
public async Task<IEnumerable<FileMetadata>> GetAllFilesAsync()
{
return await _storageService.GetAllFilesAsync();
}
// Delete a file
public async Task<bool> DeleteFileAsync(string fileName)
{
return await _storageService.DeleteFileAsync(fileName);
}
}
Advanced Configuration
// Manual configuration
services.AddS3Storage(s3Settings =>
{
s3Settings.AccessKeyId = "your-key";
s3Settings.SecretAccessKey = "your-secret";
s3Settings.Region = "us-east-1";
s3Settings.DefaultBucketName = "my-bucket";
}, resilienceSettings =>
{
resilienceSettings.MaxRetryAttempts = 5;
resilienceSettings.CircuitBreakerFailureThreshold = 3;
});
🏥 Health Checks
The library includes built-in health checks to monitor S3 connectivity:
// Add health checks
services.AddHealthChecks()
.AddS3HealthCheck("s3-storage");
// In Startup.cs or Program.cs
app.MapHealthChecks("/health");
Health check endpoint returns:
- ✅ Healthy - S3 bucket is accessible
- ❌ Unhealthy - Connection issues or bucket not accessible
🛠️ Resilience Features
Retry Policies
- Exponential Backoff - Intelligent delay between retries
- Max Attempts - Configurable retry limits
- Jittered Delays - Prevents thundering herd problems
Circuit Breaker
- Failure Threshold - Opens circuit after consecutive failures
- Recovery Time - Automatic circuit recovery
- Fast Fail - Immediate failure during circuit open state
Timeout Handling
- Request Timeouts - Per-operation timeout configuration
- Cancellation Support - Proper cancellation token handling
📊 Logging
The library provides structured logging for all operations:
// Example log output
[INFO] File uploaded to S3 and metadata stored. FileName: document.pdf
[INFO] File downloaded from S3. FileName: document.pdf, Size: 1024 bytes
[WARN] Retry attempt 2/3 for S3 operation. FileName: document.pdf
[ERROR] S3 operation failed after all retry attempts. FileName: document.pdf
🔧 Supported Storage Providers
- Amazon S3 - Native AWS S3 support
- MinIO - Self-hosted S3-compatible storage
- DigitalOcean Spaces - S3-compatible object storage
- Any S3-Compatible Storage - Standard S3 API compliance
📋 Requirements
- .NET 8.0 or higher
- AWS SDK for .NET (included)
- Polly v8 for resilience (included)
- Microsoft.Extensions.* packages (included)
🎮 Quick Start Example
Install the package:
dotnet add package NextGenPowerToys.Storage.S3.LightConfigure your app:
services.AddS3Storage(configuration);Use in your controller:
[ApiController] public class FilesController : ControllerBase { private readonly IFileStorageService _storage; public FilesController(IFileStorageService storage) { _storage = storage; } [HttpPost("upload")] public async Task<IActionResult> Upload(IFormFile file) { var request = new FileUploadRequest { File = file }; var result = await _storage.UploadFileAsync(request); return Ok(new { FileId = result.Id, Size = result.FileSize }); } }
📚 API Reference
IFileStorageService Methods
| Method | Description | Returns |
|---|---|---|
UploadFileAsync(request) |
Upload a file to storage | FileUploadResponse |
DownloadFileAsync(fileName) |
Download file by name | FileDownloadResponse |
GetFileMetadataAsync(fileName) |
Get file metadata | FileMetadata? |
GetAllFilesAsync() |
List all files | IEnumerable<FileMetadata> |
DeleteFileAsync(fileName) |
Delete a file | bool |
GenerateDownloadUrlAsync(fileName, expiry) |
Create pre-signed URL | string |
Configuration Options
S3Storage Settings
| Setting | Description | Required | Default | Example |
|---|---|---|---|---|
AccessKeyId |
AWS S3 or MinIO access key identifier. Used for authentication with the S3 service. | ✅ Yes | None | "AKIAIOSFODNN7EXAMPLE" |
SecretAccessKey |
AWS S3 or MinIO secret access key. Keep this secure and never expose in client-side code. | ✅ Yes | None | "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" |
ServiceUrl |
Custom S3 endpoint URL. Use for MinIO or other S3-compatible services. Leave empty for AWS S3. | ❌ No | None | "http://localhost:9000" |
DefaultBucketName |
Default S3 bucket name for file operations. Must exist or be created automatically. | ✅ Yes | None | "my-app-storage" |
Region |
AWS region where your S3 bucket is located. Required for AWS S3, optional for MinIO. | ❌ No | "us-east-1" |
"us-west-2" |
ForcePathStyle |
Use path-style URLs (bucket.s3.amazonaws.com vs s3.amazonaws.com/bucket). Required for MinIO. | ❌ No | false |
true for MinIO |
UseServerSideEncryption |
Enable AWS S3 server-side encryption (AES256). Not supported by all S3-compatible services. | ❌ No | false |
true |
S3Resilience Settings
| Setting | Description | Required | Default | Recommended |
|---|---|---|---|---|
MaxRetryAttempts |
Maximum number of retry attempts for failed S3 operations before giving up. | ❌ No | 3 |
3-5 |
BaseDelaySeconds |
Initial delay in seconds before the first retry attempt. Used as base for exponential backoff. | ❌ No | 1 |
1-2 |
MaxDelaySeconds |
Maximum delay in seconds between retry attempts. Prevents excessive wait times. | ❌ No | 30 |
30-60 |
UseExponentialBackoff |
Enable exponential backoff with jitter. Increases delay between retries to reduce server load. | ❌ No | true |
true |
CircuitBreakerFailureThreshold |
Number of consecutive failures before opening the circuit breaker. | ❌ No | 5 |
3-10 |
CircuitBreakerDurationSeconds |
Time in seconds the circuit stays open before attempting recovery. | ❌ No | 30 |
30-120 |
RequestTimeoutSeconds |
Maximum time in seconds to wait for a single S3 operation to complete. | ❌ No | 60 |
30-120 |
Environment-Specific Examples
AWS S3 Production:
{
"S3Storage": {
"AccessKeyId": "AKIAIOSFODNN7EXAMPLE",
"SecretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
"DefaultBucketName": "my-production-bucket",
"Region": "us-east-1",
"ForcePathStyle": false,
"UseServerSideEncryption": true
}
}
MinIO Development:
{
"S3Storage": {
"AccessKeyId": "minioadmin",
"SecretAccessKey": "minioadmin123",
"ServiceUrl": "http://localhost:9000",
"DefaultBucketName": "dev-bucket",
"Region": "us-east-1",
"ForcePathStyle": true,
"UseServerSideEncryption": false
}
}
High-Traffic Production:
{
"S3Resilience": {
"MaxRetryAttempts": 5,
"BaseDelaySeconds": 2,
"MaxDelaySeconds": 60,
"UseExponentialBackoff": true,
"CircuitBreakerFailureThreshold": 10,
"CircuitBreakerDurationSeconds": 120,
"RequestTimeoutSeconds": 90
}
}
🤝 Contributing
Contributions are welcome! Please feel free to submit pull requests, report bugs, or suggest features.
📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
🏷️ Version
Current version: 1.4.0
🔗 Links
- Repository: https://github.com/alexkonoplevgmailcom/storage-s3-light
- NuGet Package: NextGenPowerToys.Storage.S3.Light
- Issues: Report a bug or request a feature
NextGen PowerToys - Empowering developers with powerful, easy-to-use tools. 🚀
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net8.0
- AWSSDK.S3 (>= 4.0.7.4)
- Microsoft.AspNetCore.Http.Features (>= 5.0.17)
- Microsoft.Extensions.Configuration.Abstractions (>= 8.0.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Diagnostics.HealthChecks (>= 8.0.0)
- Microsoft.Extensions.Logging.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Options (>= 8.0.2)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 8.0.0)
- Polly (>= 8.6.4)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
NextGen PowerToys S3 Light v1.5.1 features:
- Comprehensive README with detailed configuration explanations
- Production-ready with MIT License
- StorageService class for cleaner API
- File name-based identifiers for intuitive usage
- AWS S3 and MinIO full compatibility
- Advanced resilience patterns with Polly v8
- Built-in health monitoring and checks
- Pre-signed URL generation
- Comprehensive structured logging
- Server-side encryption support
- .NET 8.0 optimized performance