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

如何在.NET MAUI应用中使用内置DI?注入报错问题排查

问题分析与解决方案

问题根源

  1. 页面未注册到DI容器:仅注册了TodoViewModel,但Shell导航时需从DI容器获取页面实例才能自动注入构造函数依赖,未注册页面会导致框架尝试用无参构造创建实例,触发报错。
  2. 构造函数缺失InitializeComponent()调用:XAML页面的部分类必须通过该方法加载XAML布局,缺失会导致UI无法渲染,同时框架无法正确识别页面结构。
  3. Shell导航未适配DI解析逻辑:直接通过nameof(Page)导航时,Shell默认反射创建无参实例,不会走DI容器的实例化流程。

修复步骤

1. 补全页面构造函数的核心初始化代码

修改TodoPage构造函数,添加InitializeComponent()调用(XAML页面必备):

namespace Todo.Views;

public partial class TodoPage : ContentPage
{
    public TodoPage(ViewModels.TodoViewModel viewModel)
    {
        InitializeComponent(); // 必须添加此行,加载XAML布局
        BindingContext = viewModel;
    }

    private async void Add_Todo_Clicked(object sender, EventArgs e)
    {
        await Shell.Current.GoToAsync(nameof(AddTodoPage));
    }
}

2. 将页面注册到DI容器

在MauiProgram.cs的ConfigureServices方法中,把页面与ViewModel一起注册为Transient生命周期:

private static void ConfigureServices(IServiceCollection services)
{
    services.AddTransient<TodoViewModel>();
    services.AddTransient<TodoPage>(); // 注册TodoPage到DI容器
    services.AddTransient<AddTodoPage>(); // 同步注册AddTodoPage
}

3. 配置Shell路由(推荐显式注册)

在AppShell.xaml中注册路由,确保Shell导航时从DI容器获取页面实例:

<Shell xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
       xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
       xmlns:views="clr-namespace:Todo.Views"
       x:Class="Todo.AppShell">

    <!-- 注册页面路由 -->
    <ShellContent Route="TodoPage" ContentTemplate="{DataTemplate views:TodoPage}" />
    <ShellContent Route="AddTodoPage" ContentTemplate="{DataTemplate views:AddTodoPage}" />

</Shell>

4. 保持导航逻辑的一致性

导航时使用路由名称(与注册的Route值匹配),确保Shell通过DI解析实例:

await Shell.Current.GoToAsync(nameof(TodoPage));

关于属性注入失败的说明

MAUI默认DI容器不支持属性注入,且若页面是Shell通过反射无参构造创建的,容器完全未参与实例化过程,自然无法完成属性注入。只有让DI容器负责页面实例的创建(即注册页面到DI),才能实现依赖注入。

内容的提问来源于stack exchange,提问作者Kirk Friend

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 23:52:30