Provider-agnostic blob storage contract for .NET developers — application code depends on IBlobService and the
shared models, and a provider package (AWS S3, Azure Storage, or the local filesystem) supplies the implementation.
IBlobService.BinaryData-based API —
no separate byte[] overload to choose.BlobStreamData
overloads and OpenReadAsync.Use a .NET 10 console project. This package has no IBlobService implementation of its own, so install it together
with the Local provider to run the example.
dotnet new console -f net10.0 -n BlobDemo
cd BlobDemo
dotnet add package DKNet.Svc.BlobStorage.Abstractions
dotnet add package DKNet.Svc.BlobStorage.Local
dotnet add package Microsoft.Extensions.Logging
using DKNet.Svc.BlobStorage.Abstractions;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
var config = new ConfigurationBuilder()
.AddInMemoryCollection(new Dictionary<string, string?>
{
["BlobStorage:LocalFolder:RootFolder"] = Path.Combine(Path.GetTempPath(), "blob-demo")
})
.Build();
var services = new ServiceCollection().AddLogging().AddLocalDirectoryBlobService(config);
using var provider = services.BuildServiceProvider();
var blobService = provider.GetRequiredService<IBlobService>();
var blob = new BlobDetails.BlobData("reports/hello.txt", BinaryData.FromString("Hello blob storage")) { Overwrite = true };
var location = await blobService.SaveAsync(blob);
Console.WriteLine(location); // reports/hello.txt
Run with dotnet run.
This package ships no IBlobService implementation — only the contract, the shared BlobService base class, the
request/result models, and BlobServiceOptions. The diagram cannot show that BlobService.ValidateFile and
GetBlobLocation are protected virtual: a provider can call them as-is or override them to change the rules.
Every SaveAsync call runs the same two shared steps before a provider ever touches its backing store, and only the
last step differs per backend. The diagram does not show the streaming path: SaveAsync(BlobData) is the abstract member each provider
implements, and the default SaveAsync(BlobStreamData) buffers the stream into BinaryData and delegates to it, so
the same validation and location logic applies to both.