InvalidOperationException:无法从 Blazor 中的单例“...IAuthentication”使用范围服务“Microsoft.JSInterop.IJSRuntime”

use*_*437 3 c# singleton blazor

我创建Blazor项目,起初一切正常,直到我需要注入IJSRuntimecs文件中。

Microsoft.JSInterop;
...
...

public BaseService(IJSRuntime jSRuntime)
{
}
Run Code Online (Sandbox Code Playgroud)

BaseService在另一个名为的服务中继承,该服务AuthenticationServices也使用名为 的接口IAuthentication。因此

using Microsoft.JSInterop;

public class AuthenticationServices : BaseService, IAuthentication
{
    public AuthenticationServices(IJSRuntime jSRuntime) : base(jSRuntime)
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

我的问题是在Startup.cs包含此代码的文件中

services.AddSingleton<IAuthentication, AuthenticationServices>();
Run Code Online (Sandbox Code Playgroud)

如果我运行该应用程序,它会说,

InvalidOperationException: Cannot consume scoped service 'Microsoft.JSInterop.IJSRuntime' from singleton '...IAuthentication'
Run Code Online (Sandbox Code Playgroud)

这是什么意思?我是否正确地只需要添加一些东西?

cod*_*ion 7

Blazor 中的依赖注入有 3 种不同的生命周期策略。

  • 单身人士
  • 范围
  • 短暂的

单身人士

这意味着该类型的任何服务都将只有一个实例。

范围

这个生命周期意味着对于创建的一组对象scope并且在该范围内将只有一个实例。通常在大多数情况下,创建作用域是为了处理用户会话(客户端 Blazor)或用户连接(服务器端 Blazor)。您可以与每个 HTTP 请求 (ASP.NET) 的范围进行比较。

短暂的

每次请求时都会创建具有此生命周期的对象。和普通的一样new

终身消费规则

鉴于这些对象生命周期策略的性质,以下用于使用服务的规则适用。

  • Transient服务可以使用Transient, Scoped andSingleton` 服务。
  • Scopedservice 可以消费ScopedSingleton服务。但不能消费Transient服务。
  • Singleton服务只能消费Singleton服务。但不能消费TransientScoped服务。

服务IJSRuntime注册内Blazor的Scoped服务,因此它只能由使用ScopedTransient服务。

所以,你要么必须做AuthenticationServicesScoped服务,或摆脱IJSRuntime作为构造参数。