AbYzzX.Avalonia.Modular
0.0.7.1
dotnet add package AbYzzX.Avalonia.Modular --version 0.0.7.1
NuGet\Install-Package AbYzzX.Avalonia.Modular -Version 0.0.7.1
<PackageReference Include="AbYzzX.Avalonia.Modular" Version="0.0.7.1" />
<PackageVersion Include="AbYzzX.Avalonia.Modular" Version="0.0.7.1" />
<PackageReference Include="AbYzzX.Avalonia.Modular" />
paket add AbYzzX.Avalonia.Modular --version 0.0.7.1
#r "nuget: AbYzzX.Avalonia.Modular, 0.0.7.1"
#:package AbYzzX.Avalonia.Modular@0.0.7.1
#addin nuget:?package=AbYzzX.Avalonia.Modular&version=0.0.7.1
#tool nuget:?package=AbYzzX.Avalonia.Modular&version=0.0.7.1
Avalonia.Modular
A modular application framework for Avalonia UI that enables building applications with a clean, maintainable, and pluggable architecture.
Overview
Avalonia.Modular provides a module system for Avalonia applications, allowing you to organize your application into independent, reusable modules with dependency management, lifecycle hooks, and built-in dependency injection support.
Features
- Modular Architecture: Break down your Avalonia application into independent, self-contained modules
- Dependency Management: Define dependencies between modules using the
[DependsOn]attribute - Lifecycle Hooks: Control initialization and shutdown phases of your modules
- Service Integration: Built-in support for dependency injection with
IServiceCollection - Application Context: Centralized context for managing application-wide state and services
- Configuration Support: Integrated configuration system with
IConfiguration - Splat Integration: Built-in support for Splat dependency resolver
- Type-Safe: Fully typed API leveraging C# 13.0 features
Installation
dotnet add package Avalonia.Modular
Getting Started
There are two ways to use Avalonia.Modular:
Option 1: Using ModularApplication (Recommended)
This is the simplest approach that handles all the boilerplate for you.
1. Create Your Application Class
public class App : ModularApplication<MainWindow, AppModule>
{
public override void Initialize()
{
AvaloniaXamlLoader.Load(this);
}
}
2. Define Your Main Window
public class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
3. Create Your Application Module
public class AppModule : AvaloniaModule
{
public override void ConfigureServices(IServiceCollection services)
{
// Register your services
services.AddSingleton<IMyService, MyService>();
services.AddTransient<MyViewModel>();
}
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
// Initialize your module
var myService = context.ServiceProvider.GetRequiredService<IMyService>();
myService.Initialize();
}
}
4. Configure Your Program.cs
public static AppBuilder BuildAvaloniaApp()
=> AppBuilder.Configure<App>()
.UseModularApplication()
.UsePlatformDetect()
.WithInterFont()
.ConfigureConfiguration(c => c.AddJsonFile("appsettings.json"))
.LogToTrace();
Option 2: Using AppBuilder Extensions
For more control over the application lifecycle, you can use the extension method approach.
public static AppBuilder BuildAvaloniaApp()
=> AppBuilder.Configure<App>()
.UsePlatformDetect()
.UseModular<MyModule>()
.LogToTrace();
Module System
Creating a Module
Modules are the building blocks of your application. Each module encapsulates a specific feature or domain.
public class CoreModule : AvaloniaModule
{
public override void ConfigureServices(IServiceCollection services)
{
// Register core services
services.AddSingleton<IDataService, DataService>();
services.AddSingleton<ILogger, Logger>();
}
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
// Initialize core functionality
var logger = context.ServiceProvider.GetRequiredService<ILogger>();
logger.Info("Core module initialized");
}
public override void OnApplicationShutdown(ApplicationShutdownContext context)
{
// Cleanup resources
var logger = context.ServiceProvider.GetRequiredService<ILogger>();
logger.Info("Core module shutting down");
}
}
Module Dependencies
Use the [DependsOn] attribute to define dependencies between modules. The framework will ensure modules are initialized in the correct order.
[DependsOn(typeof(CoreModule))]
public class UIModule : AvaloniaModule
{
// This module will be initialized after CoreModule
public override void ConfigureServices(IServiceCollection services)
{
services.AddTransient<MainViewModel>();
services.AddTransient<SettingsViewModel>();
}
}
[DependsOn(typeof(CoreModule), typeof(UIModule))]
public class FeatureModule : AvaloniaModule
{
// This module depends on both CoreModule and UIModule
}
Module Lifecycle
Modules go through several lifecycle phases:
- Module Loading: Modules and their dependencies are discovered and ordered
- Service Configuration:
ConfigureServices()is called for all modules - Post Configuration:
PostConfigureServices()is called for additional setup - Pre-Initialization:
OnPreApplicationInitialization()is called before app starts - Initialization:
OnApplicationInitialization()is called when the application starts - Shutdown:
OnApplicationShutdown()is called when the application is closing
public class MyModule : AvaloniaModule
{
public override void ConfigureServices(IServiceCollection services)
{
// Phase 2: Register services
services.AddSingleton<IMyService, MyService>();
}
public override void PostConfigureServices(AppContext context)
{
// Phase 3: Additional configuration after all modules have registered services
}
public override void OnPreApplicationInitialization(ApplicationBuilderInitializationContext context)
{
// Phase 4: Pre-initialization tasks
}
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
// Phase 5: Initialize module
var myService = context.ServiceProvider.GetRequiredService<IMyService>();
myService.Start();
}
public override void OnApplicationShutdown(ApplicationShutdownContext context)
{
// Phase 6: Cleanup resources
var myService = context.ServiceProvider.GetRequiredService<IMyService>();
myService.Stop();
}
}
Application Context
The AppContext provides centralized access to application-wide resources:
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
// Access service provider
var serviceProvider = context.ServiceProvider;
// Access configuration
var config = context.ServiceProvider.GetRequiredService<IConfiguration>();
var connectionString = config["ConnectionString"];
// Access services
var myService = context.ServiceProvider.GetService<IMyService>();
var requiredService = context.ServiceProvider.GetRequiredService<IRequiredService>();
}
Configuration
Avalonia.Modular supports standard .NET configuration:
public static AppBuilder BuildAvaloniaApp()
=> AppBuilder.Configure<App>()
.UseModularApplication()
.ConfigureConfiguration(builder =>
{
builder.AddJsonFile("appsettings.json", optional: false);
builder.AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ENVIRONMENT")}.json", optional: true);
builder.AddEnvironmentVariables();
})
.UsePlatformDetect();
Then use it in your modules:
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
var config = context.ServiceProvider.GetRequiredService<IConfiguration>();
var apiUrl = config["ApiSettings:Url"];
}
Logging
Configure logging during application initialization:
public static AppBuilder BuildAvaloniaApp()
=> AppBuilder.Configure<App>()
.UseModularApplication()
.ConfigureInitLogger(() =>
{
return new SerilogLoggerFactory(
new LoggerConfiguration()
.MinimumLevel.Debug()
.WriteTo.Console()
.CreateLogger())
.CreateLogger("InitLogger");
})
.UsePlatformDetect();
Service Provider Factory
Avalonia.Modular supports custom service provider factories (e.g., Autofac, DryIoc):
public static AppBuilder BuildAvaloniaApp()
=> AppBuilder.Configure<App>()
.UseModularApplication()
.ConfigureServiceProviderFactory(new AutofacServiceProviderFactory())
.UsePlatformDetect();
Complete Example
Here's a complete example application:
Program.cs
public class Program
{
[STAThread]
public static void Main(string[] args) => BuildAvaloniaApp()
.StartWithClassicDesktopLifetime(args);
public static AppBuilder BuildAvaloniaApp()
=> AppBuilder.Configure<App>()
.UseModularApplication()
.UseReactiveUI()
.UsePlatformDetect()
.WithInterFont()
.ConfigureConfiguration(c => c.AddJsonFile("appsettings.json"))
.LogToTrace();
}
App.cs
public class App : ModularApplication<MainWindow, AppModule>
{
}
AppModule.cs
public class AppModule : AvaloniaModule
{
public override void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IDataService, DataService>();
services.AddTransient<MainViewModel>();
}
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
var dataService = context.ServiceProvider.GetRequiredService<IDataService>();
dataService.Initialize();
}
}
MainWindow.cs
public class MainWindow : Window
{
public MainWindow(MainViewModel viewModel)
{
InitializeComponent();
DataContext = viewModel;
}
}
Requirements
- .NET 9.0 or later
- Avalonia UI 11.0 or later
- C# 13.0
License
This project is licensed under the terms specified in the project license file.
Contributing
Contributions are welcome! Please feel free to submit issues and pull requests.
Built with ❤️ for the Avalonia community
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- AbYzzX.System.Extensions (>= 0.0.7.1)
- Autofac (>= 8.3.0)
- Autofac.Extensions.DependencyInjection (>= 9.0.0)
- Avalonia (>= 11.3.8)
- Avalonia.Browser (>= 11.3.8)
- Avalonia.Desktop (>= 11.3.8)
- Avalonia.ReactiveUI (>= 11.3.8)
- Microsoft.Extensions.Configuration (>= 9.0.4)
- Microsoft.Extensions.Configuration.Abstractions (>= 9.0.4)
- Microsoft.Extensions.DependencyInjection (>= 9.0.4)
- Microsoft.Extensions.Logging (>= 9.0.4)
- Microsoft.Extensions.Logging.Abstractions (>= 9.0.4)
- Microsoft.Extensions.Logging.Configuration (>= 9.0.4)
- Microsoft.Extensions.Logging.Console (>= 9.0.4)
- Microsoft.Extensions.Options (>= 9.0.4)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 9.0.4)
- ReactiveUI (>= 20.2.45)
- Splat (>= 15.3.1)
- Splat.Microsoft.Extensions.DependencyInjection (>= 15.3.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.