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 原生容器完全够用。










