namespace LiteCharms.Features.S3.Abstractions; public abstract class S3ServiceBase(IAmazonS3 amazonS3) { protected readonly IAmazonS3 Client = amazonS3; protected abstract string BucketName { get; } protected abstract string CdnBaseUrl { get; } public virtual async Task> UploadFileAsync(string fileName, Stream fileStream, string contentType, CancellationToken cancellationToken = default) { try { if (string.IsNullOrWhiteSpace(BucketName)) return Result.Fail("Bucket name is not configured."); if (string.IsNullOrWhiteSpace(CdnBaseUrl)) return Result.Fail("CDN base URL is not configured."); var fileKey = $"{Guid.NewGuid():N}{Path.GetExtension(fileName)}"; var putRequest = new PutObjectRequest { BucketName = BucketName, Key = fileKey, InputStream = fileStream, ContentType = contentType, UseChunkEncoding = false }; var response = await Client.PutObjectAsync(putRequest, cancellationToken); return response.HttpStatusCode != System.Net.HttpStatusCode.OK ? Result.Fail($"Failed to upload {fileName} to S3.") : Result.Ok($"{CdnBaseUrl}/{fileKey}"); } catch (Exception ex) { return Result.Fail(new Error($"Error uploading {fileName} to S3: {ex.Message}").CausedBy(ex)); } } }