Skip to content

Repository files navigation

NuGet StatsBuildCode Coverage

Akavache

Akavache: An Asynchronous Key-Value Store for Native Applications

Akavache is an asynchronous, persistent (i.e., writes to disk) key-value store created for writing desktop and mobile applications in C#, based on SQLite3. Akavache is great for both storing important data (i.e., user settings) as well as cached local data that expires.

What's New in V12

Akavache V12 rewrites the SQLite backend for direct SQLitePCLRaw 3.x access, replacing the sqlite-net-pcl ORM layer entirely. The result is lower per-operation allocations, dedicated worker-thread serialization of all native handle access, and commit coalescing for concurrent writes.

  • SQLitePCLRaw direct access: Prepared statements cached and reused, parameters bound positionally — no ORM overhead
  • SQLite3MultipleCiphers: Encrypted databases use SQLite3MC instead of sqlcipher
  • Observable-first settings: SettingsBase properties are IObservable<T> — no more .Wait() deadlocks
  • AOT-safe serialization: JsonTypeInfo<T> overloads for System.Text.Json, trim-safe out of the box
  • System.Text.Json package split: Pure JSON package no longer pulls in Newtonsoft.Json
  • Thread-safe disposal: All cache types use lock-free Interlocked patterns for idempotent dispose

See the Migration Guide: V11 to V12 for upgrade instructions.

Quick Start

1. Install Packages

<PackageReferenceInclude="Akavache.Sqlite3"Version="*" />
<PackageReferenceInclude="Akavache.SystemTextJson"Version="*" />

2. Initialize Akavache

Note:WithAkavache, WithAkavacheCacheDatabase and Initialize always requires an ISerializer defined as a generic type, such as WithAkavache<SystemJsonSerializer>. This ensures the cache instance is properly configured for serialization.

Static Initialization (Recommended for most apps)

usingAkavache.Core;usingAkavache.SystemTextJson;usingAkavache.Sqlite3;usingSplat.Builder;// Initialize with the builder patternAppBuilder.CreateSplatBuilder().WithAkavacheCacheDatabase<SystemJsonSerializer>(builder =>builder.WithSqliteProvider()// REQUIRED: Explicitly initialize SQLite provider.WithSqliteDefaults(),"MyApp");

Important: Always call WithSqliteProvider() explicitly before WithSqliteDefaults(). While WithSqliteDefaults() will automatically call WithSqliteProvider() if not already initialized (for backward compatibility), this automatic behavior is deprecated and may be removed in future versions. Explicit provider initialization is the recommended pattern for forward compatibility with other DI containers.

Dependency Injection Registration (for DI containers)

usingAkavache.Core;usingAkavache.SystemTextJson;usingAkavache.Sqlite3;usingSplat.Builder;// Example: Register Akavache with Splat DIAppBuilder.CreateSplatBuilder().WithAkavache<SystemJsonSerializer>("MyApp",
builder =>builder.WithSqliteProvider()// REQUIRED: Explicit provider initialization.WithSqliteDefaults(),(splat,instance)=>splat.RegisterLazySingleton(()=>instance));// For in-memory cache (testing or lightweight scenarios):AppBuilder.CreateSplatBuilder().WithAkavache<SystemJsonSerializer>("Akavache",
builder =>builder.WithInMemoryDefaults(),// No provider needed for in-memory(splat,instance)=>splat.RegisterLazySingleton(()=>instance));

3. Use the Cache

Basic Operations

// Store an objectvaruser=newUser{Name="John",Email="john@example.com"};awaitCacheDatabase.UserAccount.InsertObject("current_user",user);// Retrieve an objectvarcachedUser=awaitCacheDatabase.UserAccount.GetObject<User>("current_user");// Store with expirationawaitCacheDatabase.LocalMachine.InsertObject("temp_data",someData,DateTimeOffset.Now.AddHours(1));// Get or fetch patternvardata=awaitCacheDatabase.LocalMachine.GetOrFetchObject("api_data",async()=>awaithttpClient.GetFromJsonAsync<ApiResponse>("https://api.example.com/data"));

Cache Types

Akavache provides four types of caches:

  • UserAccount: User settings and preferences that should persist and potentially sync
  • LocalMachine: Cached data that can be safely deleted by the system
  • Secure: Encrypted storage for sensitive data like credentials and API keys
  • InMemory: Temporary storage that doesn't persist between app sessions
// User preferences (persistent)awaitCacheDatabase.UserAccount.InsertObject("user_settings",settings);// API cache (temporary)awaitCacheDatabase.LocalMachine.InsertObject("api_cache",apiData,DateTimeOffset.Now.AddHours(6));// Sensitive data (encrypted)awaitCacheDatabase.Secure.SaveLogin("john.doe","secretPassword","myapp.com");// Session data (in-memory only)awaitCacheDatabase.InMemory.InsertObject("current_session",sessionData);

NuGet Packages

Install the packages that match your needs. At minimum you need the core package plus a storage backend and a serializer.

PurposePackageNuGet
Core (in-memory cache)AkavacheAkavacheBadge
SQLite persistenceAkavache.Sqlite3Sqlite3Badge
Encrypted SQLite persistenceAkavache.EncryptedSqlite3EncryptedBadge
System.Text.Json serializer (recommended)Akavache.SystemTextJsonSTJBadge
System.Text.Json BSON serializerAkavache.SystemTextJson.BsonSTJBsonBadge
Newtonsoft.Json serializerAkavache.NewtonsoftJsonNewtonsoftBadge
HTTP download and caching extensionsAkavache.HttpDownloaderHttpBadge
Image/bitmap cachingAkavache.DrawingDrawingBadge
Application settings helpersAkavache.SettingsSettingsBadge
V10 → V11 data migrationAkavache.V10toV11MigrationBadge

Installation

Akavache uses a modular package structure. Choose the packages that match your needs:

Core Package (In Memory only)

<PackageReferenceInclude="Akavache"Version="*" />

Storage Backends (Choose One - Recommended)

<!-- SQLite persistence (most common) -->
<PackageReferenceInclude="Akavache.Sqlite3"Version="*" />
<!-- Encrypted SQLite persistence -->
<PackageReferenceInclude="Akavache.EncryptedSqlite3"Version="*" />

Serializers (Choose One - Required)

<!-- System.Text.Json (fastest, .NET native) -->
<PackageReferenceInclude="Akavache.SystemTextJson"Version="*" />
<!-- Newtonsoft.Json (most compatible) -->
<PackageReferenceInclude="Akavache.NewtonsoftJson"Version="*" />

Optional Extensions

<!-- HTTP download and caching extensions -->
<PackageReferenceInclude="Akavache.HttpDownloader"Version="*" />
<!-- Image/Bitmap support -->
<PackageReferenceInclude="Akavache.Drawing"Version="*" />
<!-- Settings helpers -->
<PackageReferenceInclude="Akavache.Settings"Version="*" />

Framework Support

Akavache supports:

  • .NET Framework 4.6.2/4.7.2 - Windows desktop applications
  • .NET Standard 2.0 - Cross-platform libraries
  • .NET 8.0 - Modern .NET applications
  • .NET 9.0 - Latest .NET applications
  • .NET 10.0 - Latest .NET applications
  • Mobile Targets - net9.0-android, net9.0-ios, net9.0-maccatalyst, net10.0-android, net10.0-ios, net10.0-maccatalyst
  • Desktop Targets - net9.0-windows10.0.19041.0, net10.0-windows10.0.19041.0 (WinUI), net9.0, net10.0 (cross-platform)

Serializer Compatibility

Serializer.NET Framework 4.6.2+.NET 8.0+MobilePerformance
System.Text.Json✅ Via NuGetFastest
Newtonsoft.Json✅ Built-inCompatible

Recommendation: Use System.Text.Json for new projects for best performance. Use Newtonsoft.Json when migrating from older Akavache versions or when you need maximum compatibility.

Akavache.Settings: Configuration Made Easy

Akavache.Settings provides a specialized settings database for application configuration that survives app updates and reinstalls.

Quick Settings Example

usingAkavache.Settings;// 1. Create a settings class — properties are IObservable<T>publicclassAppSettings:SettingsBase{publicAppSettings():base(nameof(AppSettings)){}publicIObservable<bool>EnableNotifications=>GetOrCreateObservable(true);publicIObservable<Unit>SetEnableNotifications(boolvalue)=>SetObservable(value,nameof(EnableNotifications));publicIObservable<string>UserName=>GetOrCreateObservable("DefaultUser");publicIObservable<Unit>SetUserName(stringvalue)=>SetObservable(value,nameof(UserName));}// 2. Initialize with your appvarappSettings=default(AppSettings);AppBuilder.CreateSplatBuilder().WithAkavache<SystemJsonSerializer>(builder =>builder.WithApplicationName("MyApp").WithSqliteProvider().WithSettingsStore<AppSettings>(settings =>appSettings=settings));// 3. Use the settings — subscribe for live updates or read onceawaitappSettings.SetUserName("John Doe");awaitappSettings.SetEnableNotifications(false);varname=awaitappSettings.UserName.FirstAsync();Console.WriteLine($"User: {name}");

Settings are automatically persisted and will survive app updates, making them perfect for user preferences and application configuration.

Documentation

📚 Complete documentation is available in the /docs folder:

Support and Contributing

Thanks

This project is tested with BrowserStack.

We want to thank the following contributors and libraries that help make Akavache possible:

Core Libraries

  • SQLite: SQLitePCLRaw and SQLite3MultipleCiphers - SQLite access and encryption for .NET
  • System.Reactive: Reactive Extensions for .NET - The foundation of Akavache's asynchronous API
  • Splat: Splat - Cross-platform utilities and service location
  • System.Text.Json: Microsoft's high-performance JSON serializer
  • Newtonsoft.Json: James Newton-King's Json.NET - The most popular .NET JSON library

Microsoft

We thank Microsoft for their ongoing support of the .NET ecosystem and the development tools that make Akavache possible.

License

Akavache is licensed under the MIT License.

About

An asynchronous, persistent key-value store created for writing desktop and mobile applications, based on SQLite3. Akavache is great for both storing important data as well as cached local data that expires.

Topics

Resources

Code of conduct

Contributing

Stars

2.5k stars

Watchers

100 watching

Forks

Releases

Sponsor this project

Used by

Contributors

Languages