Kanject.Core.FileRepository
An S3 wrapper that treats object storage as a typed store with stream-friendly uploads, presigned upload/download links, and private/public storage locations. Register one repository, inject IFileRepository, and skip the raw AWS SDK ceremony.
Install
dotnet add package Kanject.Core.FileRepository.Provider.AwsS3 The AWS S3 provider package pulls in Kanject.Core.FileRepository.Abstractions (which defines IFileRepository) transitively.
Register
using Kanject.Core.FileRepository.Provider.AwsS3.Abstractions.Extensions;builder.Services.AddAwsS3FileRepository(options =>{ options.BucketName = appSettings.UploadsBucket; options.Region = appSettings.AwsRegion; // Credentials resolve from configuration — in a deployed Kanject // service these come from Parameter Store / Secrets Manager at deploy. options.AWSAccessKey = appSettings.AwsAccessKey; options.AWSSecretKey = appSettings.AwsSecretKey;}); AddAwsS3FileRepository registers IFileRepository as a singleton. Keyed overloads — AddAwsS3FileRepository("thumbnails", …) — let one service talk to several buckets, resolved with [FromKeyedServices].
Use it
public class AvatarService(IFileRepository files){ // Upload a stream. Returns the stored file name, its URL, and — for a // private object served via a signed link — the URL's expiry. public async Task<string> UploadAsync(Guid userId, Stream content, string contentType) { UploadFileResponse result = await files.UploadFileAsync( content, name: "avatar", path: $"users/{userId}", contentType: contentType, storageLocation: StorageLocationEnum.Public); return result.FileUrl; } // A time-limited download link for a private object. Expiry is a per-call // DateTime, not a global setting; fileAccess scopes what the link permits. public string SignedInvoiceLink(string invoiceName) { (string fileName, string link) = files.GenerateFileLink( DateTime.UtcNow.AddHours(1), name: invoiceName, storageLocation: StorageLocationEnum.Private, fileAccess: FileAccessTypeEnum.Read); return link; }} What ships with it
UploadFileAsync(Stream …)and anIFormFileoverload →UploadFileResponse { FileName, FileUrl, FileUrlExpiryDate }GetFileAsync(→Stream),GetFileAsByteArrayAsync(→byte[]), andGetFileWithMetadataAsyncDeleteFileAsync,FileExistsAsync, andGetFileMetadataAsyncGenerateFileLink(...)/GenerateUploadFileLink(...)— presigned download/upload links, expiry passed per call as aDateTimeStorageLocationEnum(Private/Public) selects the storage folder;FileAccessTypeEnum(Read/Write/Delete) scopes a signed link- Bucket lifecycle helpers on the settings — expiration and incomplete-multipart-upload cleanup
Was this page helpful?