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

在NUnit中获取ASP.NET Core 3.1应用作用域解决服务解析错误

在NUnit中获取ASP.NET Core 3.1应用作用域的解决方法

错误原因

你遇到的Cannot resolve scoped service 'className' from root provider错误,本质是ASP.NET Core的DI规则限制:根服务提供者(Root Provider)是单例生命周期的,不能直接解析作用域(Scoped)服务,必须创建一个子作用域来获取这类服务。和NUnit与应用是否同作用域无关,核心是测试中没有正确创建服务作用域。

解决方法

下面提供两种在NUnit测试中正确获取应用作用域的方式:

方式1:使用WebApplicationFactory(推荐,适合集成测试)

这是ASP.NET Core官方推荐的测试方式,会自动初始化完整的应用服务容器和Web环境。

  1. 安装NuGet包:
    安装适配ASP.NET Core 3.1的Microsoft.AspNetCore.Mvc.Testing包(版本选3.1.x系列),同时确保已安装NUnit相关测试包。

  2. 编写测试类:

using NUnit.Framework;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.Extensions.DependencyInjection;

[TestFixture]
public class ScopedServiceTests : WebApplicationFactory<Startup>
{
    [Test]
    public void CanResolveScopedService()
    {
        // 通过根服务提供者创建子作用域
        using var scope = Services.CreateScope();
        var scopeProvider = scope.ServiceProvider;

        // 在作用域内解析Scoped服务
        var targetService = scopeProvider.GetRequiredService<className>();

        // 执行你的测试逻辑
        // 例如验证服务的方法输出
        // Assert.IsNotNull(targetService);
        // Assert.AreEqual(expectedValue, targetService.SomeMethod());
    }
}

方式2:手动构建WebHost(轻量场景)

如果不需要完整Web环境,可手动构建WebHost来获取服务容器:

using NUnit.Framework;
using Microsoft.AspNetCore.WebHost;
using Microsoft.Extensions.DependencyInjection;

[TestFixture]
public class ManualScopeTests
{
    private IServiceProvider _rootServiceProvider;

    [SetUp]
    public void SetupTest()
    {
        // 构建WebHost,复用项目的Startup配置
        var webHost = WebHost.CreateDefaultBuilder()
            .UseStartup<Startup>()
            .Build();

        _rootServiceProvider = webHost.Services;
    }

    [Test]
    public void UseScopedServiceInTest()
    {
        using var scope = _rootServiceProvider.CreateScope();
        var scopedService = scope.ServiceProvider.GetRequiredService<className>();

        // 测试逻辑
    }

    [TearDown]
    public void CleanupTest()
    {
        // 释放资源
        if (_rootServiceProvider is IDisposable disposable)
        {
            disposable.Dispose();
        }
    }
}

关键注意点

  • 无论哪种方式,必须通过CreateScope()创建子作用域,再在作用域内解析Scoped服务,不能直接用根服务提供者获取。
  • WebApplicationFactory会自动处理WebHost的生命周期,无需手动释放;手动构建方式要记得在TearDown中清理资源。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 20:01:11