Storage feature for CdCSharp.Pangea - Cross-platform file and data storage
Modern Avalonia Toolkit with Intelligent MVVM, Advanced Binding, Dynamic Theming and Persistent Storage
Pangea is a comprehensive, production-ready toolkit for Avalonia UI applications that brings modern development patterns and intelligent code generation to cross-platform desktop development. Built with performance, developer experience, and maintainability in mind.
# Install the complete toolkit
dotnet add package CdCSharp.Pangea# Core functionality
dotnet add package CdCSharp.Pangea.Core
# Individual features
dotnet add package CdCSharp.Pangea.Binding
dotnet add package CdCSharp.Pangea.Theming
dotnet add package CdCSharp.Pangea.Storage
dotnet add package CdCSharp.Pangea.Localization// App.axaml.cs
using CdCSharp.Pangea;
public partial class App : PangeaApplication
{
public override void Configure(IServiceCollection services)
{
// Register your services
services.AddTransient<MainViewModel>();
services.AddSingleton<IDataService, DataService>();
}
}
// Program.cs
public static AppBuilder BuildAvaloniaApp()
=> AppBuilder.Configure<App>()
.UsePlatformDetect()
.WithInterFont()
.LogToTrace()
.UsePangea(); // 🌍 Enable Pangeausing CdCSharp.Pangea.Binding.Attributes;
using CdCSharp.Pangea.Core.Base;
public partial class ProductViewModel : ViewModelBase
{
// 🏷️ Fields with [Binding] become full properties with change notifications
[Binding] private string _name = "";
[Binding] private decimal _price;
[Binding] private bool _isAvailable = true;
[Binding] private ObservableCollection<string> _categories = new();
// ⚙️ Computed properties automatically detect dependencies
public string DisplayName => $"{Name} ({Price:C})";
public bool CanOrder => IsAvailable && Price > 0;
// 🎯 Commands with automatic CanExecute binding
public RelayCommand OrderCommand => CreateCommand(ExecuteOrder, () => CanOrder);
public RelayCommand<string> AddCategoryCommand => CreateCommand<string>(AddCategory);
private void ExecuteOrder()
{
// Order logic here
IsAvailable = false; // Automatically updates CanOrder and OrderCommand.CanExecute
}
private void AddCategory(string? category)
{
if (!string.IsNullOrEmpty(category))
Categories.Add(category);
}
// 🔄 Partial methods for custom change handling
partial void OnNameChanged()
{
// Custom logic when Name changes
// DisplayName automatically updates too!
}
}The Functional Analyzer examines your ViewModel and generates optimized code:
// ✨ Auto-generated by Pangea's Intelligent Binding System
public partial class ProductViewModel
{
public string Name
{
get => _name;
set
{
if (SetProperty(ref _name, value))
{
OnNameChanged();
// 🧠 Smart dependency detection
OnPropertyChanged(nameof(DisplayName)); // Computed property
OrderCommand.NotifyCanExecuteChanged(); // Command dependency
}
}
}
public decimal Price
{
get => _price;
set
{
if (SetProperty(ref _price, value))
{
OnPriceChanged();
// 🔗 Transitive dependencies automatically resolved
OnPropertyChanged(nameof(DisplayName));
OnPropertyChanged(nameof(CanOrder));
OrderCommand.NotifyCanExecuteChanged();
}
}
}
// 🚀 Full implementation for all binding fields...
}Pangea's FunctionalAnalyzer performs sophisticated static analysis of your ViewModels:
[Binding] attributed fields and their characteristicsRelayCommand properties and their CanExecute conditionsOnPropertyChanged partial methods and tracked method callsOnPropertyChanged callspublic partial class AdvancedViewModel : ViewModelBase
{
[Binding] private string _firstName = "";
[Binding] private string _lastName = "";
[Binding] private decimal _salary;
[Binding] private bool _isManager;
[Binding] private ObservableCollection<Employee> _directReports = new();
// 🧠 Complex computed properties with multiple dependencies
public string FullName => $"{FirstName} {LastName}".Trim();
public string DisplayTitle => IsManager ? $"Manager: {FullName}" : FullName;
public decimal AnnualBonus => IsManager ? Salary * 0.15m : Salary * 0.05m;
public bool HasDirectReports => DirectReports.Count > 0;
// 🎯 Commands with complex CanExecute logic
public RelayCommand PromoteCommand => CreateCommand(Promote, () => !IsManager && Salary > 50000);
public RelayCommand<Employee> RemoveReportCommand => CreateCommand<Employee>(RemoveReport, emp => emp != null && HasDirectReports);
// 🔄 Collection modification with automatic dependent updates
private void AddDirectReport(Employee employee)
{
DirectReports.Add(employee);
// 🚀 Pangea automatically notifies: HasDirectReports, RemoveReportCommand.CanExecute
}
// 🎛️ Complex partial method with cascade handling
partial void OnSalaryChanged()
{
UpdateBenefits();
RecalculateTeamBudget();
// 🧠 Pangea handles: AnnualBonus, PromoteCommand.CanExecute notifications
}
}
// ✨ Generated notifications are precisely calculated:
// Changing FirstName triggers: FullName → DisplayTitle
// Changing IsManager triggers: DisplayTitle, AnnualBonus, PromoteCommand.CanExecute
// Changing Salary triggers: AnnualBonus, PromoteCommand.CanExecute + custom partial method// Runtime theme switching
public partial class SettingsViewModel : ViewModelBase
{
private readonly IThemeService _themeService;
public RelayCommand<string> ChangeThemeCommand => CreateCommand<string>(theme =>
{
_themeService.SetTheme(theme);
// Theme changes immediately across entire application
});
}public partial class UserPreferencesViewModel : ViewModelBase
{
[Binding] private string _username = "";
[Binding] private ThemeMode _preferredTheme = ThemeMode.System;
// 💾 Automatic persistence
private readonly IStorageService _storage;
partial void OnUsernameChanged() => _storage.SaveAsync("username", Username);
partial void OnPreferredThemeChanged() => _storage.SaveAsync("theme", PreferredTheme);
}// Localization with binding support
public partial class LocalizedViewModel : ViewModelBase
{
private readonly ILocalizationService _localization;
public string WelcomeMessage => _localization.GetString("Welcome", Username);
public string ItemCount => _localization.GetString("ItemCount", Items.Count);
}public partial class App : PangeaApplication
{
public override PangeaOptions ConfigurePangeaOptions(PangeaOptions options)
{
return options with
{
DI = options.DI with
{
AutoRegisterViewModels = true,
ViewModelLifetime = ServiceLifetime.Scoped
},
Window = options.Window with
{
AutoDiscoverMainWindow = true,
MainWindowType = typeof(MainWindow),
MainViewModelType = typeof(MainViewModel)
}
};
}
public override void Configure(IServiceCollection services)
{
// Advanced service registration
services.AddSingleton<ICustomService, CustomService>();
services.AddHttpClient<IApiClient, ApiClient>();
// Storage configuration
services.Configure<StorageOptions>(options =>
{
options.Provider = StorageProvider.SQLite;
options.ConnectionString = "Data Source=app.db";
});
// Theme configuration
services.Configure<ThemingOptions>(options =>
{
options.DefaultTheme = "Dark";
options.AllowRuntimeSwitching = true;
});
}
}public class CloudStorageProvider : IStorageProvider
{
public async Task<T?> GetAsync<T>(string key)
{
// Custom cloud storage implementation
return await _cloudClient.GetAsync<T>(key);
}
public async Task SaveAsync<T>(string key, T value)
{
await _cloudClient.SaveAsync(key, value);
}
}
// Register in DI
services.AddTransient<IStorageProvider, CloudStorageProvider>();Pangea uses a modular architecture where each feature is self-contained:
[TestClass]
public class ProductViewModelTests
{
[TestMethod]
public void PropertyChanges_TriggerDependentUpdates()
{
// Arrange
var viewModel = new ProductViewModel();
var notificationCount = 0;
viewModel.PropertyChanged += (s, e) => notificationCount++;
// Act
viewModel.Name = "Test Product";
// Assert - Verify Pangea generated the right notifications
Assert.IsTrue(notificationCount >= 2); // Name + DisplayName
Assert.AreEqual("Test Product", viewModel.DisplayName);
}
}| Feature | Pangea | CommunityToolkit.Mvvm | ReactiveUI | Prism |
|---|---|---|---|---|
| 🧠 Intelligent Analysis | ✅ Advanced | ❌ Basic | ❌ Manual | ❌ Manual |
| ⚡ Source Generation | ✅ Full | ✅ Partial | ❌ Reflection | ❌ Reflection |
| 🎨 Dynamic Theming | ✅ Built-in | ❌ None | ❌ None | ❌ Custom |
| 💾 Storage Integration | ✅ Multi-provider | ❌ None | ❌ Custom | ❌ Custom |
| 🌐 Localization | ✅ Integrated | ❌ External | ❌ External | ✅ Built-in |
| 🏗️ DI Container | ✅ Built-in | ❌ External | ✅ Splat | ✅ Built-in |
| 📱 Cross-Platform | ✅ Avalonia | ❌ WPF/WinUI | ✅ Multi | ✅ Multi |
We welcome contributions! Please see our Contributing Guide for details.
git checkout -b feature/amazing-feature)git commit -m 'Add amazing feature')git push origin feature/amazing-feature)
This project is licensed under the MIT License - see the LICENSE file for details.
⭐ If Pangea helps your project, please give it a star! ⭐
Made with ❤️ for the Avalonia and .NET community