You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MAUI Hybrid应用启动预加载数据:依赖注入服务使用问题

问题描述

我的MAUI Hybrid应用需要在首页面渲染时检查用户登录状态,从而获取用户专属数据。我尝试在App.xaml.cs的CreateWindow事件中执行预加载任务,但此时依赖注入服务似乎无法正常使用。CustomAuthenticationStateProvider是一个重写了AuthenticationStateProvider.GetAuthenticationStateAsync()的服务,用于在Maui SecureStorage存在有效令牌时验证用户身份。请问如何在启动阶段执行可使用依赖注入服务的代码?

App.xaml.cs 代码示例:

public partial class App : Application
{
    [Inject] CustomAuthenticationStateProvider authStateProvider { get; set; }

    public App()
    {
        InitializeComponent();

        MainPage = new MainPage();
    }

    protected override Window CreateWindow(IActivationState activationState)
    {
        Window window = base.CreateWindow(activationState);

        window.Created += (s, e) =>
        {
            _ = PreloadTasks();
        };

        return window;
    }

    public async Task PreloadTasks()
    {
        var state = await authStateProvider.GetAuthenticationStateAsync();
        if (state.User.Identity.IsAuthenticated)
        {
            //preload user specific data while Ui is rendering
        }
    }
}

Program.cs 代码示例:

builder.Services.AddAuthorizationCore();
builder.Services.AddScoped<CustomAuthenticationStateProvider>();
builder.Services.AddScoped<AuthenticationStateProvider>(s => s.GetRequiredService<CustomAuthenticationStateProvider>());
return builder.Build();

问题根源

你代码里的[Inject]属性未生效,因为默认情况下App实例是通过new App()直接创建的,而非由依赖注入容器实例化,导致属性注入逻辑未被触发,authStateProvider会是null。

解决方案

这里提供两种可行的解决方式:

方式一:通过窗口的MauiContext获取服务(无需修改App创建逻辑)

直接在CreateWindow的Created事件中,从窗口的MauiContext获取DI服务,绕过App实例的注入问题:

修改App.xaml.cs的CreateWindow方法:

protected override Window CreateWindow(IActivationState activationState)
{
    Window window = base.CreateWindow(activationState);

    window.Created += async (s, e) =>
    {
        // 从窗口的MauiContext获取服务提供者
        var services = ((Window)s).Handler.MauiContext.Services;
        var authStateProvider = services.GetRequiredService<CustomAuthenticationStateProvider>();
        
        var state = await authStateProvider.GetAuthenticationStateAsync();
        if (state.User.Identity.IsAuthenticated)
        {
            // 在UI渲染的同时预加载用户专属数据
        }
    };

    return window;
}

这种方式无需改动Program.cs,直接利用窗口初始化后的上下文获取服务,简单高效。

方式二:让App由DI容器实例化(支持属性注入)

修改Program.cs,将App注册为服务并由DI容器创建,使[Inject]属性正常生效:

  1. 更新Program.cs:
builder.Services.AddAuthorizationCore();
builder.Services.AddScoped<CustomAuthenticationStateProvider>();
builder.Services.AddScoped<AuthenticationStateProvider>(s => s.GetRequiredService<CustomAuthenticationStateProvider>());
// 将App注册为DI服务
builder.Services.AddTransient<App>();

var appBuilder = builder.Build();
// 从DI容器获取App实例并运行
var app = appBuilder.Services.GetRequiredService<App>();
app.Run();
  1. 保持App.xaml.cs原有代码不变即可,此时[Inject]的authStateProvider会被DI容器正确注入,PreloadTasks方法能正常调用服务。

注意事项

  • 方式一适合快速解决当前问题,无需改动App的创建逻辑;
  • 方式二更符合依赖注入设计原则,适合后续需要在App类中使用更多DI服务的场景;
  • 你当前用_ = PreloadTasks();异步执行预加载的方式可以避免阻塞UI渲染,处理得没问题。

内容的提问来源于stack exchange,提问作者Matias Masso

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 13:00:50