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

WPF中Entity Framework依赖注入时出现对象引用异常

问题分析与解决方案

问题根源

你的LoginViewModel被注册为Singleton单例生命周期,但KnitterNotebookContext默认是Scoped作用域生命周期。单例依赖作用域服务会导致DI容器无法正确解析:作用域服务需要在活动作用域内创建,而单例初始化时没有可用的作用域,最终引发对象引用异常。此外,若LoginWindow的DataContext是手动实例化而非DI注入,也会导致依赖缺失。


具体解决方案

1. 统一服务生命周期

将LoginWindow和LoginViewModel的注册改为Scoped,与DbContext的默认生命周期匹配:

.ConfigureServices((hostContext, services) =>
{
    // 替换Singleton为Scoped,与DbContext生命周期对齐
    services.AddScoped<LoginWindow>();
    services.AddScoped<LoginViewModel>();

    services.AddDbContext<KnitterNotebookContext>(
        options =>
        {
            // 推荐使用Host内置配置系统读取连接字符串,替代手动JSON解析
            var connectionString = hostContext.Configuration.GetConnectionString("KnitterNotebookConnectionString");
            options.UseSqlServer(connectionString);
        });
})

2. 启动时创建作用域获取服务

修改OnStartup方法,通过创建服务作用域来解析Scoped类型的窗口:

protected override async void OnStartup(StartupEventArgs e)
{
    await AppHost!.StartAsync();
    // 创建作用域以正确解析Scoped服务
    using var scope = AppHost.Services.CreateScope();
    var startupWindow = scope.ServiceProvider.GetRequiredService<LoginWindow>();
    startupWindow.Show();
    base.OnStartup(e);
}

3. 确保窗口通过DI注入ViewModel

修改LoginWindow的构造函数,接收LoginViewModel并设置为DataContext,避免手动实例化:

public partial class LoginWindow : Window
{
    public LoginWindow(LoginViewModel viewModel)
    {
        InitializeComponent();
        DataContext = viewModel;
    }
}

4. 优化连接字符串配置(可选)

在appsettings.json中配置连接字符串,让Host自动读取:

{
  "ConnectionStrings": {
    "KnitterNotebookConnectionString": "你的SQL Server连接字符串"
  }
}

同时确保appsettings.json的复制到输出目录属性设置为始终复制,避免运行时找不到文件。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 07:25:39