.net - GraphQL Hot Chocolate Constructor DI 在第二次请求时失败
问题描述
我正在使用用户身份验证服务构建 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>>();
}
这是配置 GraphghQL 的扩展方法
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 仅适用于第一个请求。
有什么我做错了吗?
解决方案
因此,如果您不声明任何内容,Hot Chocolate 会将解析器类添加为单例。在您的情况下,UserManager<User>
我认为这是一项范围服务。因此,在您的案例中使用构造函数注入的每个解析器类都需要在 DI 和范围服务中注册。
或者,您可以使用解析器级别 DI。
public async Task<User> LoginAsync(LoginDto loginDto, [Service] UserManager<User> userManager)
{
var user = await userManager.FindByEmailAsync(loginDto.Email);
return user;
}
我个人倾向于使用解析器级别 DI,因为它更清楚执行期间需要什么。但这取决于你。
推荐阅读
- tensorflow - 如何在 Tensorflow 的小批量中进行选择性反向传播?
- c++ - 不能包含来自静态库的头文件 (VS17)
- sql - 文本匹配 SQL 查询,根据主题查找相似匹配,但限制完全匹配
- css - 如何使用 CSS 隐藏类中的特定文本?
- python - Python 到 SQL 连接。试图将熊猫数据框推送到 SQL Server
- react-native - 在 React Native 中从 fetch 中导出 JSON
- laravel - 尝试将添加到购物车的项目添加到导航栏
- layout - 程序忽略了 setPreferredSize 的使用
- java - Selenium 使窗口失焦
- python-3.x - 测试进行网络往返的单个 DAG