Introduction
Resourcefull is a .NET library for storing files in your own infrastructure and serving them from your application. Your code uploads, downloads, lists, versions and deletes files through one client API, and a storage provider decides where the bytes go: the SQL Server or PostgreSQL database you already run, a directory on your own disks, process memory in tests, or a store of your own.
It's for applications that keep files people upload or download, such as invoices, profile pictures, reports, contract scans or video, and want them next to the rest of their data, on servers they run. When an application moves to the cloud, its code stays the same apart from the line that picks the provider, which switches to Amazon S3, another S3-compatible store or Azure Blob Storage. When to use Resourcefull compares it with the alternatives.
The building blocks
A few words come up on every page:
- A resource is a file: its content, plus a description that Resourcefull keeps with it, called its
ResourceInfo: its name, content type, length, a SHA-256 hash of its content, metadata you choose, and when it was stored. - A container is a named group of resources, such as
invoicesoruser-42. Every resource lives in one, and two resources can have the same name in different containers. See Containers. - A version is one stored copy of a resource's content. Uploading again stores a new version, and the newest is the current one. With versioning turned on, older versions are kept so you can go back to them.
- The service client,
IResourceServiceClient, is what your code injects. It creates and deletes containers, and hands out a container client,IResourceContainerClient, for working with the resources in one container. - A provider stores the bytes. You choose one when you register Resourcefull, and your code doesn't change if you switch.
IResourceContainerClient invoices = await resources.CreateContainerIfNotExistsAsync("invoices");
ResourceInfo stored = await invoices.UploadAsync("2026/10/invoice-1042.pdf", pdf);
ResourceDownloadResult? download = await invoices.DownloadStreamingAsync("2026/10/invoice-1042.pdf");
The packages
| Package | What it's for |
|---|---|
Resourcefull |
The client API every application uses. |
Resourcefull.SqlServer |
Stores files in a SQL Server database. Use it in production. |
Resourcefull.PostgreSql 4.0 |
Stores files in a PostgreSQL database. Use it in production. |
Resourcefull.Sqlite 4.0 |
Stores files in a SQLite database file, with no server to run. |
Resourcefull.FileSystem 4.0 |
Stores files in a directory, on a local disk or a network share. Use it in production. |
Resourcefull.S3 4.0 |
Stores files in Amazon S3 or another S3-compatible object store. Use it in production. |
Resourcefull.AzureBlob 4.0 |
Stores files in Azure Blob Storage. Use it in production. |
Resourcefull.InMemory |
Keeps files in process memory, for tests and local development. |
Resourcefull.AspNetCore |
Serves and accepts files over HTTP with the right status codes and headers, and creates signed links for sharing them. |
Where to go next
- New to Resourcefull? Getting started installs a package, registers a provider, and stores and reads your first file.
- Working with files: uploading, downloading, listing, copying and moving, versioning, and what happens when several callers write at once (concurrency).
- Building a web app: the ASP.NET Core section serves downloads, accepts uploads and shares files with links.
- Managing storage: container policies for quotas and file types, expiring resources, and backing up and moving containers.
- Running in production: setting up SQL Server, PostgreSQL, SQLite, the file system, S3-compatible storage or Azure Blob Storage, health checks, telemetry and troubleshooting.
- Testing and extending: testing with the in-memory provider, and writing a provider of your own.
- Looking something up? The API reference lists every public type and member, and Errors lists what each operation returns or throws.
- What's new, and what's next? See Releases and roadmap.
Contributing to Resourcefull itself? See CONTRIBUTING.md.