Acontplus.S3Application 2.0.2

There is a newer version of this package available.
See the version list below for details.
dotnet add package Acontplus.S3Application --version 2.0.2
                    
NuGet\Install-Package Acontplus.S3Application -Version 2.0.2
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Acontplus.S3Application" Version="2.0.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Acontplus.S3Application" Version="2.0.2" />
                    
Directory.Packages.props
<PackageReference Include="Acontplus.S3Application" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Acontplus.S3Application --version 2.0.2
                    
#r "nuget: Acontplus.S3Application, 2.0.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Acontplus.S3Application@2.0.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Acontplus.S3Application&version=2.0.2
                    
Install as a Cake Addin
#tool nuget:?package=Acontplus.S3Application&version=2.0.2
                    
Install as a Cake Tool

Acontplus.S3Application

NuGet .NET License

Production-ready AWS S3 storage library with enterprise-grade scalability, resilience, and performance optimizations. Built for high-throughput cloud-native applications.


๐Ÿ“‘ Table of Contents


๐Ÿš€ Features

v2.0.0 - Scalability & Resilience

  • โšก Connection Pooling: Reuses S3 clients per credentials/region (25x faster)
  • ๐Ÿ”„ Polly Retry Policy: Automatic exponential backoff for transient failures
  • ๐Ÿšฆ Rate Limiting: Prevents AWS throttling (configurable requests/second)
  • โš™๏ธ Configurable Resilience: Customize timeouts, retries, and delays
  • ๐Ÿ“Š Structured Logging: Detailed operation metrics and diagnostics
  • ๐Ÿงต Thread-Safe: ConcurrentDictionary for multi-threaded workloads
  • โ™ป๏ธ IDisposable: Proper resource cleanup and disposal
  • ๐ŸŽฏ Dependency Injection: Full DI support with IOptions<T> pattern

Core Capabilities

  • Async S3 CRUD: Upload, update, delete, and retrieve S3 objects
  • Presigned URLs: Generate secure, time-limited download links
  • Strong Typing: Models for S3 objects, credentials, and responses
  • Business Error Handling: Consistent, metadata-rich responses
  • .NET 10: Nullable, required properties, and latest C# features

๐Ÿ“ฆ Installation

NuGet Package Manager

Install-Package Acontplus.S3Application -Version 2.0.0

.NET CLI

dotnet add package Acontplus.S3Application --version 2.0.0

PackageReference

<PackageReference Include="Acontplus.S3Application" Version="2.0.0" />

๐ŸŽฏ Quick Start

1. Register the Service (Required in v2.0+)

using Acontplus.S3Application.Extensions;

// In Program.cs or Startup.cs
var builder = WebApplication.CreateBuilder(args);

// Option 1: Load configuration from appsettings.json (recommended)
builder.Services.AddS3Storage(builder.Configuration);

// Option 2: Configure explicitly
builder.Services.AddS3Storage(options =>
{
    options.MaxRequestsPerSecond = 100;
    options.TimeoutSeconds = 60;
    options.MaxRetries = 3;
    options.RetryBaseDelayMs = 500;
    options.Region = "us-east-1";
});

// Option 3: Use all defaults
builder.Services.AddS3Storage();

2. Configure appsettings.json (Flexible - All Optional)

{
  "AWS": {
    "S3": {
      "MaxRequestsPerSecond": 100,
      "TimeoutSeconds": 60,
      "MaxRetries": 3,
      "RetryBaseDelayMs": 500,
      "Region": "us-east-1",
      "DefaultBucketName": "my-bucket",
      "ForcePathStyle": false,
      "EnableMetrics": false
    },
    "AccessKey": "AKIA...",
    "SecretKey": "secret..."
  }
}

Note:

  • All AWS:S3 settings are optional with sensible defaults
  • Use AWS:AccessKey/SecretKey for credentials (modern approach)
  • Credentials are optional when using IAM roles or EC2 instance profiles
  • Legacy keys (S3Bucket, AwsConfiguration) are supported for backward compatibility but deprecated - avoid in new projects

3. Basic Usage Example

public class FileUploadController : ControllerBase
{
    private readonly IS3StorageService _s3Service;
    private readonly IConfiguration _configuration;

    public FileUploadController(IS3StorageService s3Service, IConfiguration configuration)
    {
        _s3Service = s3Service;
        _configuration = configuration;
    }

    [HttpPost("upload")]
    public async Task<IActionResult> Upload(IFormFile file)
    {
        var s3Object = new S3ObjectCustom(_configuration);
        await s3Object.Initialize("uploads/", file);

        var response = await _s3Service.UploadAsync(s3Object);

        return response.StatusCode == 201
            ? Ok(new { message = response.Message, url = s3Object.S3ObjectUrl })
            : StatusCode(response.StatusCode, response.Message);
    }
}

โš™๏ธ Configuration

S3StorageOptions (AWS:S3 section)

All settings are optional with production-ready defaults:

Setting Default Description
MaxRequestsPerSecond 100 Rate limit to prevent AWS throttling
TimeoutSeconds 60 Request timeout in seconds
MaxRetries 3 Retry attempts for transient failures
RetryBaseDelayMs 500 Base delay for exponential backoff
Region null AWS region (falls back to S3Bucket:Region)
DefaultBucketName null Default bucket for operations
ForcePathStyle false Use path-style URLs (S3-compatible services)
EnableMetrics false Enable detailed request metrics

AWS Credentials Configuration

Credentials can be configured via unified keys (recommended) or legacy keys (deprecated):

Unified Key (Use This) Legacy Key (Deprecated) Required Description
AWS:AccessKey AwsConfiguration:AWSAccessKey No* AWS access key ID
AWS:SecretKey AwsConfiguration:AWSSecretKey No* AWS secret access key
AWS:S3:DefaultBucketName S3Bucket:Name Yes** S3 bucket name
AWS:S3:Region S3Bucket:Region No AWS region (default: us-east-1)

โš ๏ธ Deprecation Notice: Legacy keys (S3Bucket:*, AwsConfiguration:*) are maintained for backward compatibility but should not be used in new projects. They will be removed in v3.0.0.

* Credentials are optional when using:

  • IAM roles (EC2 instances, ECS tasks)
  • Instance profiles
  • AWS credentials file (~/.aws/credentials)

** Required only when using S3ObjectCustom with IConfiguration

Flexible Configuration Examples

Recommended (unified keys):

{
  "AWS": {
    "S3": {
      "DefaultBucketName": "my-bucket",
      "Region": "us-east-1"
    },
    "AccessKey": "AKIA...",
    "SecretKey": "secret..."
  }
}

โš ๏ธ Legacy keys (deprecated - avoid in new projects):

{
  "S3Bucket": {
    "Name": "my-bucket",
    "Region": "us-east-1"
  },
  "AwsConfiguration": {
    "AWSAccessKey": "AKIA...",
    "AWSSecretKey": "secret..."
  }
}

IAM Roles (no credentials needed):

{
  "AWS": {
    "S3": {
      "DefaultBucketName": "my-bucket",
      "Region": "us-east-1"
    }
  }
}

High-Throughput Workload:

{
  "AWS": {
    "S3": {
      "MaxRequestsPerSecond": 200,
      "MaxRetries": 5,
      "TimeoutSeconds": 120
    }
  }
}

S3-Compatible Services (MinIO, DigitalOcean Spaces):

{
  "AWS": {
    "S3": {
      "ForcePathStyle": true,
      "Region": "us-east-1"
    }
  }
}

๐Ÿ› ๏ธ Advanced Usage

Downloading an Object

var s3Object = new S3ObjectCustom(_configuration);
s3Object.Initialize("uploads/invoice-2024.pdf");

var response = await _s3Service.GetObjectAsync(s3Object);

if (response.StatusCode == 200)
{
    return File(response.Content, response.ContentType, response.FileName);
}

Generating a Presigned URL

var s3Object = new S3ObjectCustom(_configuration);
s3Object.Initialize("uploads/report.pdf");

var urlResponse = await _s3Service.GetPresignedUrlAsync(s3Object, expirationInMinutes: 30);

if (urlResponse.StatusCode == 200)
{
    var presignedUrl = urlResponse.FileName;
    // Share URL with users - expires in 30 minutes
}

Checking if an Object Exists

var exists = await _s3Service.DoesObjectExistAsync(s3Object);

if (exists)
{
    // File exists in S3
}

Deleting an Object

var response = await _s3Service.DeleteAsync(s3Object);

if (response.StatusCode == 200)
{
    // Successfully deleted
}

๐Ÿš€ Performance

v2.0.0 Performance Improvements

Metric v1.x v2.0.0 Improvement
Connections/second 10-20 100-500 25x faster
Memory per request ~5MB ~500KB 90% reduction
Avg latency (pooled) 150-300ms 50-100ms 66% faster
CPU usage High Low-Medium 60% reduction
Transient error recovery โŒ Manual โœ… Automatic Built-in

Rate Limiting Behavior

The service automatically enforces configured rate limits:

// This will automatically throttle to 100 req/s (default)
var tasks = Enumerable.Range(0, 500)
    .Select(i => _s3Service.UploadAsync(objects[i]));

await Task.WhenAll(tasks); // Completes in ~5 seconds with smooth throttling

Connection Pooling

Clients are pooled by credentials + region:

// First call: Creates new client
await _s3Service.UploadAsync(s3Object); // ~200ms

// Subsequent calls: Reuses pooled client
await _s3Service.UploadAsync(s3Object2); // ~50ms (4x faster!)

๐Ÿ”„ Upgrade Guide

Migrating from v1.x to v2.0.0

Breaking Changes:

  1. Service registration changed from direct instantiation to DI
  2. Constructor requires IOptions<S3StorageOptions> and ILogger<S3StorageService>

Migration Steps:

// OLD (v1.x) - Remove this
services.AddScoped<IS3StorageService, S3StorageService>();

// NEW (v2.0.0) - Add this
services.AddS3Storage(configuration);

Benefits:

  • Automatic retry for transient AWS errors (503, 500, timeouts)
  • Connection pooling reduces latency by 66%
  • Rate limiting prevents throttling errors
  • Detailed logging for diagnostics

See UPGRADE_GUIDE_v2.0.0.md for complete migration instructions.


๐Ÿ“š Dependencies

  • .NET 10+
  • AWSSDK.Core 4.0.3.6+
  • AWSSDK.S3 4.0.15+
  • Polly 8.6.5+ (NEW in v2.0)
  • Microsoft.Extensions.Logging.Abstractions
  • Microsoft.Extensions.Options

๐Ÿ›ก๏ธ Error Handling

All service methods return an S3Response object with comprehensive error information:

public class S3Response
{
    public int StatusCode { get; set; }      // HTTP-like: 200, 201, 404, 500
    public string Message { get; set; }       // Success or error message
    public byte[]? Content { get; set; }      // File bytes (downloads)
    public string? ContentType { get; set; }  // MIME type
    public string? FileName { get; set; }     // File name or presigned URL
}

Retry Behavior

The service automatically retries these transient errors:

  • 503 Service Unavailable (AWS overload)
  • 500 Internal Server Error (AWS issue)
  • RequestTimeout / SlowDown (AWS throttling)
  • HttpRequestException (network issues)

Retry Schedule (default):

  • Attempt 1: Immediate
  • Attempt 2: 500ms delay
  • Attempt 3: 1s delay
  • Attempt 4: 2s delay
  • Attempt 5: 4s delay (if MaxRetries=4)

Logging

The service logs all operations with structured context:

// Successful operations
_logger.LogInformation("Successfully uploaded {Key} to bucket {Bucket}",
    "uploads/file.pdf", "my-bucket");

// Retry attempts
_logger.LogWarning("S3 operation retry {RetryCount}/{MaxRetries} after {Delay}. Error: SlowDown",
    2, 3, "1s");

// Errors
_logger.LogError("S3 error uploading {Key}: {ErrorCode} - {Message}",
    "uploads/file.pdf", "AccessDenied", "Insufficient permissions");

๐Ÿค Contributing

Contributions are welcome! Please open an issue or submit a pull request.


๐Ÿ“„ License

MIT License. See LICENSE for details.


๐Ÿ‘ค Author

Ivan Paz


๐Ÿข Company

Acontplus

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.0.3 0 1/11/2026
2.0.2 84 1/1/2026
2.0.1 177 12/23/2025
2.0.0 270 12/16/2025
1.2.4 139 12/11/2025
1.2.3 164 12/5/2025
1.2.2 198 12/3/2025
1.2.1 197 11/23/2025
1.2.0 186 11/23/2025
1.1.16 294 11/11/2025
1.1.15 199 11/5/2025
1.1.14 208 11/2/2025
1.1.13 187 10/23/2025
1.1.12 185 9/24/2025
1.1.11 242 9/14/2025
1.1.10 192 9/9/2025
1.1.9 201 9/3/2025
1.1.8 228 8/24/2025
1.1.7 177 8/19/2025
1.1.6 184 8/13/2025
1.1.5 261 8/7/2025
1.1.4 267 8/5/2025
1.1.3 142 7/31/2025
1.1.2 561 7/23/2025
1.1.1 139 7/18/2025
1.1.0 190 7/15/2025
1.0.3 177 7/10/2025
1.0.2 182 7/9/2025
1.0.1 188 7/3/2025
1.0.0 184 6/30/2025

BREAKING CHANGE v2.0.0: Major scalability improvements with connection pooling, Polly retry policies with exponential backoff, rate limiting (100 req/s default), configurable resilience options, proper IDisposable implementation, structured logging, and thread-safe operations. Requires IOptions<S3StorageOptions> and ILogger<S3StorageService> in DI. Use AddS3Storage() extension for registration.