GraphQL Hot Chocolate Constructor DI 在第二次请求中失败

Posted

技术标签:

【中文标题】GraphQL Hot Chocolate Constructor DI 在第二次请求中失败【英文标题】:GraphQL Hot Chocolate Constructor DI failed on 2nd request 【发布时间】:2021-12-10 02:05:36 【问题描述】:

我正在构建一个带有用户身份验证服务的 GraphQL 端点。对于用户身份验证,我使用的是 Entity Framework Core。

在突变解析器中,当我使用构造函数 DI [Ref] 时,第二次访问解析器时出现以下错误。 "无法访问已释放的对象。\r\n对象名称:'UserManager`1'。"

根据 Hot Chocolate 指令,构造函数 DI 是单例类型,不太清楚为什么会出现此错误。

但是,如果我使用 [Service] 关键字注入解析器方法。我没有收到任何错误 [Ref]。

public void ConfigureServices(IServiceCollection services)
        
            services.AddGraphQLService();

            services.AddDbContext<DataContext>(opt =>
            
                opt.UseSqlite(_configuration.GetConnectionString("AuthenticationConnection"));
            );

            services.AddIdentityCore<User>(opt =>
            
                opt.Password.RequireNonAlphanumeric = false;
            )
                .AddRoles<IdentityRole>()
                .AddEntityFrameworkStores<DataContext>()
                .AddSignInManager<SignInManager<User>>();

        

这是配置 GrapghQL 的扩展方法

public static IServiceCollection AddGraphQLService(this IServiceCollection services)
        
            services.AddGraphQLServer()
                .AddQueryType(q => q.Name("Query"))
                .AddTypeExtension<AlbumQueryTypeExtension>()
                .AddTypeExtension<ArtistQueryTypeExtension>()
                .AddMutationType(m => m.Name("Mutation"))
                .AddTypeExtension<ArtistMutationTypeExtension>()
                .AddTypeExtension<AuthenticationMutationTypeExtension>()
                .AddSubscriptionType<Subscription>()
                .AddInMemorySubscriptions()
                .AddAuthorization()
                ;

            return services;
        

在我的解析器中,以下方法有效,

public async Task<User> LoginAsync(LoginDto loginDto, [Service] UserManager<User> userManager)
        
            var user = await userManager.FindByEmailAsync(loginDto.Email);
            
            return user ;
        

但是如果我执行构造函数 DI,我会得到一个错误。

public class AuthenticationMutateResolvers
    
        private readonly UserManager<User> _userManager;
            
        public AuthenticationMutateResolvers(UserManager<User> userManager)
        
            _userManager = userManager;
        


        public async Task<User> LoginAsync(LoginDto loginDto)
        
            var user = await _userManager.FindByEmailAsync(loginDto.Email);
            
            return user;
        

知道为什么构造函数 DI 仅适用于第一个请求。

我做错了什么?

【问题讨论】:

你能发布配置你的GraphQL服务的方法吗。AddGraphQLService 对不起,我刚刚意识到我还没有添加那个扩展方法。我刚加了。谢谢 【参考方案1】:

因此,如果您不声明任何内容,Hot Chocolate 会将解析器类添加为单例。在您使用UserManager&lt;User&gt; 的情况下,我认为这是一项范围服务。因此,在您的案例中,每个使用构造函数注入的解析器类都需要在 DI 和范围服务中注册。

您也可以使用解析器级别 DI。

public async Task<User> LoginAsync(LoginDto loginDto, [Service] UserManager<User> userManager)

    var user = await userManager.FindByEmailAsync(loginDto.Email);
            
    return user;

我个人倾向于使用解析器级别 DI,因为它更清楚执行期间需要什么。但这取决于你。

【讨论】:

谢谢,迈克尔,现在很有意义,非常感谢您的时间。我尝试构造函数 DI 的原因是为了让类更干净。否则,当您有多个具有相同依赖项的突变时,dev 会尝试实现构造函数 DI 以使突变更加清晰。

以上是关于GraphQL Hot Chocolate Constructor DI 在第二次请求中失败的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 DataLoader 与 Hot Chocolate GraphQL 进行连接

GraphQL Hot Chocolate Constructor DI 在第二次请求中失败

如何在 .Net 5 中使用 Hot Chocolate 在 GraphQL 中修改响应 Cookie

如何在 EF Core 的 Hot Chocolate 中打开和关闭包含

嵌套对象的 ASP.NET CORE Hot Chocolate 查询错误

Hot Chocolate 无法为输入类型的字段设置默认值