# Migration from V10.x to V11.1 This guide helps you migrate from Akavache V10.x to V11.1 while preserving your existing data and functionality. ## Overview of Changes Akavache V11.1 introduces significant architectural improvements while maintaining backward compatibility with your data. The main changes are in how you initialize and configure Akavache, not in the core API you use daily. ### Breaking Changes 1. **Initialization Method**: The `BlobCache.ApplicationName` and `Registrations.Start()` methods are replaced with the builder pattern 2. **Package Structure**: Akavache is now split into multiple packages 3. **Serializer Registration**: Must explicitly register a serializer before use ### What Stays the Same - ✅ **Core API**: `GetObject`, `InsertObject`, `GetOrFetchObject` work identically - ✅ **Data Compatibility**: V11.1 reads all V10.x data without conversion - ✅ **Cache Types**: UserAccount, LocalMachine, Secure, InMemory work the same - ✅ **Extension Methods**: All your existing extension method calls work ## Migration Steps ### Step 1: Update Package References #### Old V10.x packages: ```xml ``` #### New V11.1 packages: ```xml ``` ### Step 2: Update Initialization Code #### Old V10.x Code: ```csharp // V10.x initialization BlobCache.ApplicationName = "MyApp"; // or Akavache.Registrations.Start("MyApp"); // Usage var data = await BlobCache.UserAccount.GetObject("key"); await BlobCache.LocalMachine.InsertObject("key", myData); ``` #### New V11.1 Code: ```csharp // V11.1 initialization (RECOMMENDED: Explicit provider pattern) using Akavache.Core; using Akavache.SystemTextJson; using Akavache.Sqlite3; using Splat.Builder; AppBuilder.CreateSplatBuilder() .WithAkavacheCacheDatabase(builder => builder.WithApplicationName("MyApp") .WithSqliteProvider() // REQUIRED: Explicit provider initialization .WithSqliteDefaults()); // Usage (same API) var data = await CacheDatabase.UserAccount.GetObject("key"); await CacheDatabase.LocalMachine.InsertObject("key", myData); ``` ### Step 3: Migration Helper Create this helper method to ease migration: ```csharp public static class AkavacheMigration { public static void InitializeV11(string appName) { // Initialize with SQLite (most common V10.x setup) // RECOMMENDED: Use explicit provider initialization CacheDatabase .Initialize(builder => builder .WithSqliteProvider() // Explicit provider initialization .WithSqliteDefaults(), appName); } } // Then in your app: AkavacheMigration.InitializeV11("MyApp"); ``` ## Detailed Migration Scenarios ### Scenario 1: Basic V10.x App **Before (V10.x):** ```csharp public partial class App : Application { protected override void OnStartup(StartupEventArgs e) { BlobCache.ApplicationName = "MyWpfApp"; base.OnStartup(e); } } public class DataService { public async Task GetUser(int userId) { return await BlobCache.UserAccount.GetOrFetchObject($"user_{userId}", () => apiClient.GetUser(userId), TimeSpan.FromMinutes(30)); } } ``` **After (V11.1):** ```csharp using Akavache.Core; using Akavache.SystemTextJson; using Akavache.Sqlite3; using Splat.Builder; public partial class App : Application { protected override void OnStartup(StartupEventArgs e) { AppBuilder.CreateSplatBuilder() .WithAkavacheCacheDatabase(builder => builder.WithApplicationName("MyWpfApp") .WithSqliteProvider() .WithSqliteDefaults()); base.OnStartup(e); } } public class DataService { public async Task GetUser(int userId) { // Same API! return await CacheDatabase.UserAccount.GetOrFetchObject($"user_{userId}", () => apiClient.GetUser(userId), TimeSpan.FromMinutes(30)); } } ``` ### Scenario 2: Encrypted Cache **Before (V10.x):** ```csharp BlobCache.ApplicationName = "MySecureApp"; BlobCache.SecureFileStorage = new EncryptedBlobStorage("password"); ``` **After (V11.1):** ```csharp AppBuilder.CreateSplatBuilder() .WithAkavache(builder => builder.WithApplicationName("MySecureApp") .WithEncryptedSqliteProvider() .WithSqliteDefaults("password")); ``` ### Scenario 3: Custom Storage Locations **Before (V10.x):** ```csharp BlobCache.ApplicationName = "MyApp"; BlobCache.LocalMachine = new SqliteBlobCache(@"C:\MyApp\cache.db"); ``` **After (V11.1):** ```csharp AppBuilder.CreateSplatBuilder() .WithAkavache(builder => builder.WithApplicationName("MyApp") .WithSqliteProvider() .WithLocalMachine(new SqliteBlobCache(@"C:\MyApp\cache.db")) .WithSqliteDefaults()); ``` ### Scenario 4: Dependency Injection **Before (V10.x):** ```csharp // V10.x didn't have good DI support BlobCache.ApplicationName = "MyApp"; container.RegisterInstance(BlobCache.UserAccount); ``` **After (V11.1):** ```csharp // V11.1 has first-class DI support AppBuilder.CreateSplatBuilder() .WithAkavache( "MyApp", builder => builder.WithSqliteProvider().WithSqliteDefaults(), (splat, instance) => container.RegisterInstance(instance)); ``` ## Serializer Migration ### For Maximum Compatibility (Recommended for Migration) Use Newtonsoft.Json serializer to maintain 100% compatibility: ```csharp AppBuilder.CreateSplatBuilder() .WithAkavacheCacheDatabase(builder => builder.WithApplicationName("MyApp") .WithSqliteProvider() .WithSqliteDefaults()); ``` ### For Best Performance (Recommended for New Code) Use System.Text.Json for better performance: ```csharp AppBuilder.CreateSplatBuilder() .WithAkavacheCacheDatabase(builder => builder.WithApplicationName("MyApp") .WithSqliteProvider() .WithSqliteDefaults()); ``` ## Data Migration ### Cross-Serializer Compatibility V11.1 can read data written by V10.x and different serializers: ```csharp // This works! V11.1 can read V10.x data regardless of serializer choice var oldData = await CacheDatabase.UserAccount.GetObject("key_from_v10"); ``` ### Gradual Migration You can migrate serializers gradually: ```csharp // 1. Start with Newtonsoft for compatibility AppBuilder.CreateSplatBuilder() .WithAkavacheCacheDatabase(/* ... */); // 2. Later, change to System.Text.Json for performance // Old data will still be readable! AppBuilder.CreateSplatBuilder() .WithAkavacheCacheDatabase(/* ... */); ``` ## Platform-Specific Migration ### .NET MAUI Migration **Before (V10.x):** ```csharp public partial class App : Application { public App() { InitializeComponent(); BlobCache.ApplicationName = "MyMauiApp"; MainPage = new AppShell(); } } ``` **After (V11.1):** ```csharp // In MauiProgram.cs public static class MauiProgram { public static MauiApp CreateMauiApp() { var builder = MauiApp.CreateBuilder(); builder.UseMauiApp(); // Initialize Akavache AppBuilder.CreateSplatBuilder() .WithAkavacheCacheDatabase(cacheBuilder => cacheBuilder.WithApplicationName("MyMauiApp") .WithSqliteProvider() .WithSqliteDefaults()); return builder.Build(); } } ``` ### Mobile Platform Packages Add platform-specific SQLite support: ```xml ``` ## Testing Your Migration ### 1. Verify Data Access ```csharp // Test that old data is still accessible try { var oldData = await CacheDatabase.UserAccount.GetObject("existing_key"); Console.WriteLine("✅ Migration successful - old data accessible"); } catch (Exception ex) { Console.WriteLine($"❌ Migration issue: {ex.Message}"); } ``` ### 2. Test New Data Storage ```csharp // Test that new data can be stored and retrieved var testData = new MyDataType { Value = "test" }; await CacheDatabase.UserAccount.InsertObject("migration_test", testData); var retrieved = await CacheDatabase.UserAccount.GetObject("migration_test"); Console.WriteLine(retrieved.Value == "test" ? "✅ New storage working" : "❌ Storage issue"); ``` ### 3. Performance Comparison ```csharp // Compare V10 vs V11 performance var stopwatch = System.Diagnostics.Stopwatch.StartNew(); for (int i = 0; i < 1000; i++) { await CacheDatabase.UserAccount.InsertObject($"perf_test_{i}", new MyData { Value = i }); } stopwatch.Stop(); Console.WriteLine($"1000 inserts: {stopwatch.ElapsedMilliseconds}ms"); ``` ## Troubleshooting Migration Issues ### Common Issues #### 1. "No serializer has been registered" ```csharp // Fix: Ensure you register a serializer AppBuilder.CreateSplatBuilder() .WithAkavacheCacheDatabase(/* ... */); ``` #### 2. "Provider not found" ```csharp // Fix: Call WithSqliteProvider() before WithSqliteDefaults() .WithSqliteProvider() .WithSqliteDefaults() ``` #### 3. Data not found after migration ```csharp // Check if application name changed builder.WithApplicationName("SameAsV10App") // Must match V10 app name ``` ### Migration Checklist - [ ] Updated package references - [ ] Replaced initialization code - [ ] Added explicit provider initialization - [ ] Tested existing data access - [ ] Verified new data storage - [ ] Updated DI container registration (if applicable) - [ ] Added platform-specific packages (mobile) - [ ] Updated application shutdown code ## Performance Considerations V11.1 generally performs better than V10.x, especially with System.Text.Json: - **System.Text.Json**: Faster than V10 across all scenarios - **Newtonsoft.Json**: Comparable to V10 for small/medium data, may be slower for very large datasets For best migration experience: 1. Start with Newtonsoft.Json for compatibility 2. Migrate to System.Text.Json when ready for optimal performance ## Getting Help If you encounter issues during migration: 1. Check the [Troubleshooting Guide](troubleshooting.md) 2. Review the [Configuration Documentation](configuration.md) 3. Ask on [ReactiveUI Slack](https://reactiveui.net/slack) 4. File an issue on [GitHub](https://github.com/reactiveui/Akavache/issues) Remember: V11.1 is designed to be a drop-in replacement for V10.x with better performance and more features. Your existing data and most of your code will work without changes!