C# Avalonia如何使用依赖注入 Avalonia DI框架集成教程

来源:这里教程网 时间:2026-02-21 17:41:06 作者:

在 Avalonia 中使用依赖注入(DI)和 .NET 原生的

Microsoft.Extensions.DependencyInjection
是标准做法,Avalonia 本身不提供独立的“DI 框架”,而是无缝集成 .NET 的通用主机(Generic Host)和 DI 容器。关键在于正确配置
AppBuilder
,将服务注册到容器,并在视图、视图模型或控件中通过构造函数注入。

注册服务到 Avalonia DI 容器

Avalonia 应用启动时通过

AppBuilder
配置服务。你应在
Program.cs
中调用
UseStartup<app>()</app>
或直接使用
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<app>()
        .UsePlatformDetect()
        .LogToTrace()
        .UseReactiveUI()
        .SetupWithoutStarting() // 先不启动,以便配置 DI
        .ConfigureServices((ctx, services) =>
        {
            // 注册你的服务(瞬态、作用域、单例)
            services.AddSingleton<IDataService, MockDataService>();
            services.AddScoped<MainViewModel>();
            services.AddTransient<INotificationService, ToastNotificationService>();
            // 可选:注册 Avalonia 相关服务(如窗口管理器)
            services.AddSingleton<IWindowManager, WindowManager>();
        });
}</app>

在 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<t>()</t>
(不推荐,破坏测试性)

配合 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<IDataService>(), typeof(IDataService));
    }
    base.OnFrameworkInitializationCompleted();
}

基本上就这些。Avalonia 的 DI 不复杂但容易忽略 Setup 顺序和生命周期匹配——重点是用好

ConfigureServices
,把服务注册清楚,再让 ViewModel 或必要组件通过构造函数自然消费。不需要引入第三方 DI 框架,.NET 原生容器完全够用。

相关推荐