gpt4 book ai didi

c# - 无法在测试中重现异常无法从 Mvc 框架外的单例中使用范围服务

转载 作者:行者123 更新时间:2023-12-04 10:18:26 27 4
gpt4 key购买 nike

InvalidOperationException Cannot consume scoped service from singleton是一个众所周知的场景described very well here

我正在研究一种重现此异常的方法(假设它来自依赖注入(inject)框架),但我没有成功。

我有 created a repo with a commit to illustrate it但基本上我有以下测试:

public class Given_Scoped_Repository_And_Singleton_Service_That_Uses_The_Repository_When_Getting_Service_From_Different_Scope_After_Disposing_First_Scope
: Given_When_Then_Test
{
private IServiceScope _scopeOne;
private IServiceScope _scopeTwo;
private ServiceSample _serviceSampleOne;
private ServiceSample _serviceSampleTwo;

protected override void Given()
{
var serviceCollection =
new ServiceCollection()
.AddScoped<RepositorySample>()
.AddSingleton<ServiceSample>()
.BuildServiceProvider();

_scopeOne = serviceCollection.CreateScope();
_scopeTwo = serviceCollection.CreateScope();

_serviceSampleOne = _scopeOne.ServiceProvider.GetService<ServiceSample>();

_scopeOne.Dispose();
}

protected override void When()
{
_serviceSampleTwo = _scopeTwo.ServiceProvider.GetService<ServiceSample>();
}

[Fact]
public void Then_It_Should_Get_The_Same_Service_Instance()
{
_serviceSampleOne.Should().Be(_serviceSampleTwo);
}

[Fact]
public void Then_It_Should_Have_The_Same_Repository_Instance()
{
_serviceSampleOne.RepositorySample.Should().Be(_serviceSampleTwo.RepositorySample);
}
}


class RepositorySample { }
class ServiceSample
{
public RepositorySample RepositorySample { get; }

public ServiceSample(RepositorySample repositorySample)
{
RepositorySample = repositorySample;
}
}

我希望看到 InvalidOperationException抛出,因为我从不同的范围获得单例服务,期望存储库不同(因为它是范围的)。 这些测试没有失败即使我明确地处理了第一个实例化作用域 RepositorySample 的上下文我在这里有点困惑。
  • 为什么依赖注入(inject)框架Microsoft.Extensions.DependencyInjection 3.1.3不会抛出异常提醒我单例范围陷阱吗?
  • 如果我处理第一个范围(就好像它是 Mvc 场景中的一个范围 DbContext,在发出响应时应该死掉),这不应该导致 RepositorySample要处理的实例?不是,即使我有 RepositorySample实现IDisposable我可以看到作用域实例从未被释放(Dispose 方法未执行)
  • 我如何设计我的测试来查看异常,就好像它发生在单例服务中实例化的作用域 DbContext 中一样?
  • 最佳答案

    它没有抛出异常,因为尚未指定验证范围的选项。

    改变这个:

    .BuildServiceProvider();

    对此:
    .BuildServiceProvider(new ServiceProviderOptions { ValidateScopes = true });

    ServiceProviderOptions.ValidateScopes

    true to perform check verifying that scoped services never gets resolved from root provider;



    您也可以在 ServiceProvider 时执行验证。构建而不是等到服务解决:
    .BuildServiceProvider(
    new ServiceProviderOptions
    {
    ValidateScopes = true,
    ValidateOnBuild = true
    });

    这就是 MVC 应用程序在启动时所做的事情。这就是为什么在启动时抛出异常,而不是在解析 Controller 时抛出异常。如果它检测到错误,即使注册的依赖项在运行时永远不会被解析,它也会抛出该异常。要查看它,请注册您的依赖项 - ServiceSample , RepositorySample - 正如您在单元测试中所做的那样,但不要将它们注入(inject)任何 Controller 。尝试构建 ServiceProvider 时,您仍然会在启动时遇到异常。 .

    关于c# - 无法在测试中重现异常无法从 Mvc 框架外的单例中使用范围服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60975543/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com