Your first
document.
From package to working storage in a few lines of C#.
You’ll need the .NET 10 SDK.
Pick a provider.
Start with Memory. The package includes the shared abstractions and core dependencies.
dotnet new console -n LibrarianDemo -f net10.0
cd LibrarianDemo
dotnet add package Soenneker.Librarian.Memory
Store and retrieve documents.
Replace Program.cs with this complete example, then run dotnet run. Raw JSON operations do not require generated JSON contracts.
using Microsoft.Extensions.DependencyInjection;
using Soenneker.Librarian.Abstractions;
using Soenneker.Librarian.Memory.Registrars;
var services = new ServiceCollection();
services.AddLogging();
services.AddMemoryLibrarianDatabaseAsSingleton();
await using var provider = services.BuildServiceProvider();
var database = provider.GetRequiredService<ILibrarianDatabase>();
var users = await database.GetContainer("users");
await users.AddItem("user-1", """{"name":"Alex","age":30}""");
string? json = await users.GetItem("user-1");
Console.WriteLine(json);
Register the provider on builder.Services and inject ILibrarianDatabase into your service. The database owns its containers; don’t dispose them individually.
Keep building.
Ready for typed queries? Register source-generated JSON metadata before using typed repositories, LINQ, or typed index reads.
using System.Text.Json.Serialization;
using Soenneker.Librarian.Abstractions.Serialization;
using Soenneker.Librarian.Abstractions.Queries;
// Register once, before typed operations.
LibrarianJson.Register(AppJsonContext.Default.User);
var adults = await users.BuildQueryable<User>()
.Where(user => user.Age >= 18)
.OrderBy(user => user.Age)
.Take(25)
.ToListAsync();
public sealed record User(string Name, int Age);
[JsonSourceGenerationOptions(
PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase)]
[JsonSerializable(typeof(User))]
internal partial class AppJsonContext : JsonSerializerContext;
Supported filters and ordering create indexes automatically. Provider query support differs; remote providers reject unsupported expressions instead of silently loading all documents.