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

.NET Framework 4.8 WPF如何在XAML中通过DI加载视图?

在.NET Framework 4.8 WPF中从DI容器获取XAML视图实例

核心问题原因

直接在XAML中写<rasViews:RasView/>时,WPF解析器会直接调用视图的无参构造函数创建实例,完全绕过你配置的DI容器,所以无法获取到DI注入的依赖。

解决方案:自定义XAML标记扩展

通过自定义Markup Extension,让XAML在解析时从DI容器中获取视图实例,具体步骤如下:

1. 保存DI容器的服务提供者

在App.xaml.cs中,将Host创建的IServiceProvider暴露为静态属性,方便标记扩展访问:

public partial class App : Application
{
    public static IServiceProvider ServiceProvider { get; private set; }

    protected override void OnStartup(StartupEventArgs e)
    {
        var host = Host.CreateDefaultBuilder()
            .ConfigureServices(services =>
            {
                // 注册视图和视图模型
                services.AddTransient<RasViewModel>();
                services.AddTransient<RasView>();
            })
            .Build();

        ServiceProvider = host.Services;
        base.OnStartup(e);
    }
}

2. 实现自定义DI标记扩展

创建一个继承自MarkupExtension的类,用于从DI容器中获取指定类型的实例:

using System;
using System.Windows.Markup;

namespace YourAppNamespace
{
    public class DIExtension : MarkupExtension
    {
        public Type ServiceType { get; set; }

        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            return App.ServiceProvider.GetService(ServiceType);
        }
    }
}

3. 在XAML中使用标记扩展获取视图

不再直接写<rasViews:RasView/>,而是通过自定义标记扩展从DI容器获取实例,通常用ContentControl承载:

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:YourAppNamespace"
        xmlns:rasViews="clr-namespace:YourRasViewsNamespace">

    <!-- 通过DI获取RasView实例 -->
    <ContentControl Content="{local:DIExtension ServiceType={x:Type rasViews:RasView}}"/>

</Window>

可选方案:ViewModel-First模式

如果你的视图依赖于ViewModel(构造函数注入),也可以采用ViewModel优先的方式:

  1. 在XAML中定义ViewModel到视图的DataTemplate:
<Window.Resources>
    <DataTemplate DataType="{x:Type rasViewModels:RasViewModel}">
        <rasViews:RasView/>
    </DataTemplate>
</Window.Resources>
  1. 通过标记扩展获取ViewModel实例,WPF会自动匹配DataTemplate创建视图:
<ContentControl Content="{local:DIExtension ServiceType={x:Type rasViewModels:RasViewModel}}"/>

这种方式更符合MVVM模式,且视图的依赖会由DI容器自动注入。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 21:27:25