Avalonia 使用 .net 原生 microsoft.Extensions.DependencyInjection 实现依赖注入,通过 appBuilder.ConfigureServices 注册服务,并在 ViewModel 或必要组件中通过构造函数注入;不推荐在 View 中直接注入业务服务,应交由 ViewModel 处理。

在 Avalonia 中使用依赖注入(DI)和 .NET 原生的 Microsoft.Extensions.DependencyInjection 是标准做法,Avalonia 本身不提供独立的“DI 框架”,而是无缝集成 .NET 的通用主机(Generic Host)和 DI 容器。关键在于正确配置 AppBuilder,将服务注册到容器,并在视图、视图模型或控件中通过构造函数注入。
注册服务到 Avalonia DI 容器
Avalonia 应用启动时通过 AppBuilder 配置服务。你应在 Program.cs 中调用 UseStartup 或直接使用 SetupWithoutStarting() + 手动构建主机,推荐前者以保持与 .NET 主机模式一致。
示例(.NET 6+,使用 AppBuilder):
// Program.cs using Avalonia; using Avalonia.Controls.ApplicationLifetimes; using Microsoft.Extensions.DependencyInjection; class Program { [STAThread] public static void Main(string[] args) { BuildAvaloniaApp() .StartWithClassicDesktopLifetime(args); } public static AppBuilder BuildAvaloniaApp() => AppBuilder.Configure() .UsePlatformDetect() .LogToTrace() .UseReactiveUI() .SetupWithoutStarting() // 先不启动,以便配置 DI .ConfigureServices((ctx, services) => { // 注册你的服务(瞬态、作用域、单例) services.AddSingleton(); services.AddScoped(); services.AddTransient(); // 可选:注册 Avalonia 相关服务(如窗口管理器) services.AddSingleton(); }); }
在 ViewModel 中使用构造函数注入
Avalonia 的 ViewModel 默认由 DI 容器解析(前提是你在 XAML 中启用了自动绑定或手动指定 DataContext)。只要 ViewModel 类型已注册,且其构造函数参数都能被容器解析,就能自动注入。
- 确保 ViewModel 在
ConfigureServices中注册(如Scoped或Transient) - XAML 中不要硬编码
DataContext,改用ViewModel={Binding}或依赖Locator - 推荐使用
Locator模式(reactiveUI 或自定义)统一管理 ViewModel 生命周期
例如:
public partial class Mainwindow : Window { public MainWindow() { InitializeComponent(); // 若未设置 DataContext,Avalonia 会尝试从 DI 容器解析 MainViewModel // (需启用 ReactiveUI 或自定义 Locator) } }
在 View 或 UserControl 中注入服务
View(如 Window 或 UserControl)本身**不建议直接注入业务服务**,但可在构造函数中注入生命周期短的服务(如 IWindowManager、IDialogService),前提是这些服务已在容器中注册且是 Transient 或 Scoped。
- View 构造函数支持注入,但仅限于 Avalonia 启动后容器已就绪的场景(即
SetupWithoutStarting+Start流程) - 避免在 View 中注入耗时或跨生命周期的服务(如数据库上下文),应交由 ViewModel 处理
- 若需在 View 中获取服务,也可通过
Application.Current?.Services.GetService(不推荐,破坏测试性)()
配合 ReactiveUI 使用更自然的 DI
如果你使用 ReactiveUI(Avalonia 官方推荐组合),可借助 WhenActivated 和 Locator 实现更清晰的依赖管理:
- 用
Locator.CurrentMutable.RegisterConstant(...)注册服务(适合全局单例) - ViewModel 继承
ReactiveObject并在构造函数接收依赖,ReactiveUI 自动参与 DI 解析 - 在
App.OnFrameworkInitializationCompleted中初始化Locator,与IServiceProvider对齐
简单对齐方式:
// App.xaml.cs public override void OnFrameworkInitializationCompleted() { if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) { // 将 IServiceProvider 注入 ReactiveUI Locator Locator.CurrentMutable.InitializeSplat(); Locator.CurrentMutable.InitializeReactiveUI(); Locator.CurrentMutable.Register(() => Application.Current!.Services.GetRequiredService(), typeof(IDataService)); } base.OnFrameworkInitializationCompleted(); }
基本上就这些。Avalonia 的 DI 不复杂但容易忽略 Setup 顺序和生命周期匹配——重点是用好 ConfigureServices,把服务注册清楚,再让 ViewModel 或必要组件通过构造函数自然消费。不需要引入第三方 DI 框架,.NET 原生容器完全够用。