Startup, activation, shutdown, exit).Program.cs: BuildAvaloniaApp, platform bootstrap, and app start method.App.axaml + App.axaml.cs: global resources/themes and root assignment.Views/: Window / UserControl definitions.ViewModels/: app state, commands, async workflows.Services/: I/O, storage, launcher, domain services.using System;
using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
internal static class Program
{
[STAThread]
public static int Main(string[] args)
=> BuildAvaloniaApp().StartWithClassicDesktopLifetime(args);
public static AppBuilder BuildAvaloniaApp()
=> AppBuilder.Configure<App>()
.UsePlatformDetect();
}
AppBuilder Orchestration SurfaceHigh-value app startup APIs:
Configure<TApp>(), Configure<TApp>(Func<TApp> appFactory)UseWindowingSubsystem(...), UseRenderingSubsystem(...), UseRuntimePlatformSubsystem(...), UseStandardRuntimePlatformSubsystem()With<T>(T options), With<T>(Func<T> options)ConfigureFonts(...)AfterSetup(...), AfterApplicationSetup(...), AfterPlatformServicesSetup(...)SetupWithoutStarting(), SetupWithLifetime(...), Start(AppMainDelegate, args)AppMainDelegateUseful diagnostics/introspection properties while composing startup:
Instance, ApplicationTypeWindowingSubsystemInitializer, WindowingSubsystemNameRenderingSubsystemInitializer, RenderingSubsystemNameRuntimePlatformServicesInitializer, RuntimePlatformServicesNameAfterSetupCallback, AfterPlatformServicesSetupCallbackLifetimeOverrideExample:
public static AppBuilder BuildAvaloniaApp()
=> AppBuilder.Configure<App>(() => new App())
.UsePlatformDetect()
.AfterPlatformServicesSetup(builder =>
{
// Platform services are registered here.
_ = builder.RuntimePlatformServicesName;
})
.AfterSetup(builder =>
{
// Application instance exists here.
_ = builder.Instance;
});
Application Lifecycle SurfaceApp-level events and collections often needed in production apps:
Application.ResourcesChangedApplication.ActualThemeVariantChangedApplication.UrlsOpened (obsolete compatibility event for URL activation flows)Application.DataTemplatesApplication.DataContextPropertyApplication.NamePropertyApplication.NamePattern:
public override void OnFrameworkInitializationCompleted()
{
ResourcesChanged += (_, _) => { };
ActualThemeVariantChanged += (_, _) => { };
UrlsOpened += (_, e) =>
{
// Compatibility path; prefer IActivatableLifetime for new code.
_navigation.OpenUrls(e.Urls);
};
_ = DataTemplates;
base.OnFrameworkInitializationCompleted();
}
Application identity and root data context are explicit property-system entries:
DataContextProperty (styled property owner on Application)NameProperty (direct property)Name (CLR wrapper)Example:
public override void Initialize()
{
// Set root application identity and default binding context intentionally.
Name = "MyApp";
DataContext = _rootShellState;
}
Main lifetime choices:
IClassicDesktopStyleApplicationLifetime for multi-window desktop apps.ISingleViewApplicationLifetime for single-root hosts.IActivatableLifetime for activation/deactivation flow.ISingleTopLevelApplicationLifetime when the host has exactly one TopLevel.Compatibility note:
IActivatableApplicationLifetime exists as an obsolete compatibility interface and has no effect in 11.3.12; use Application.Current.TryGetFeature<IActivatableLifetime>().Related public activation types:
ActivatableLifetimeBaseActivatedEventArgs (Kind as ActivationKind)ProtocolActivatedEventArgs (Uri)FileActivatedEventArgs (Files)Pattern:
if (ApplicationLifetime is IActivatableLifetime activatable)
{
activatable.Activated += (_, e) =>
{
if (e is ProtocolActivatedEventArgs p)
_navigation.OpenUri(p.Uri);
else if (e is FileActivatedEventArgs f)
_navigation.OpenFiles(f.Files);
};
}
Desktop-specific useful APIs:
ClassicDesktopStyleApplicationLifetime.ArgsClassicDesktopStyleApplicationLifetime.ShutdownModeClassicDesktopStyleApplicationLifetime.ShutdownRequestedClassicDesktopStyleApplicationLifetime.StartupClassicDesktopStyleApplicationLifetime.ExitClassicDesktopStyleApplicationLifetimeOptions.ProcessUrlActivationCommandLineClassicDesktopStyleApplicationLifetimeExtensionsEvent arg types used by controlled lifetime:
ControlledApplicationLifetimeStartupEventArgs (Args)ShutdownRequestedEventArgs (Cancel)ControlledApplicationLifetimeExitEventArgs (ApplicationExitCode)Pattern:
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
desktop.Startup += (_, e) =>
{
string[] args = e.Args;
_ = args.Length;
};
desktop.ShutdownRequested += (_, e) =>
{
e.Cancel = !CanCloseSafely();
};
desktop.Exit += (_, e) =>
{
e.ApplicationExitCode = 0;
};
}
Additional desktop startup helpers:
DesktopApplicationExtensions.RunWithMainWindow<TWindow>()AppBuilderDesktopExtensionsusing Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;
public class App : Application
{
public override void Initialize() => AvaloniaXamlLoader.Load(this);
public override void OnFrameworkInitializationCompleted()
{
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
desktop.MainWindow = new MainWindow
{
DataContext = new MainWindowViewModel()
};
}
else if (ApplicationLifetime is ISingleViewApplicationLifetime singleView)
{
singleView.MainView = new MainView
{
DataContext = new MainViewModel()
};
}
base.OnFrameworkInitializationCompleted();
}
}
Program.cs.
Program.cs focused on AppBuilder composition.MainWindow/MainView outside OnFrameworkInitializationCompleted().
AfterSetup/AfterPlatformServicesSetup callbacks minimal and deterministic.