SignalR:为 IUserIdProvider 使用范围内的服务
SignalR: Use scoped service for IUserIdProvider
我必须进行服务/数据库调用才能根据请求声明映射 UserId。通常,我会像这样简单地做到这一点:
public class AuthUserIdProvider : IUserIdProvider
{
private IBusinessDependencies Dependencies { get; }
public AuthUserIdProvider(IBusinessDependencies dependencies)
{
Dependencies = dependencies;
}
public string GetUserId(HubConnectionContext connection)
{
var email = connection.User.Claims.FirstOrDefault(m => m.Type.Equals(ClaimTypes.Email, StringComparison.OrdinalIgnoreCase))?.Value;
if (string.IsNullOrEmpty(email))
{
return null;
}
return Dependencies.EntityServices.UserService.GetUserByEmailCached(email).GetAwaiter().GetResult().Id.ToString();
}
}
但是 IBusinessDependencies
是有范围的,因为有一堆业务逻辑取决于特定的请求/会话。
是否可以将 IUserIdProvider
注册为作用域而不是单例?或者也许还有其他更好的解决方案?
我个人从来不需要使用 IUserIdProvider
,但我看不到任何特别 要求 它是单例的。不过,我可能错过了一些东西。但是,我想您在来这里之前至少必须尝试将其注册为作用域(希望如此)。
假设它必须是单例,那么你唯一的选择就是 service-locator 模式。不是注入 IBusinessDependencies
,而是注入 IServiceProvider
。然后每当你真正需要你的 IBusinessDependencies
实例时:
using (var scope = _serviceProvider.CreateScope())
{
var dependencies = scope.ServiceProvider.GetRequiredService<IBusinessDependencies>();
// do something with dependencies
}
如果不明显,您不能将 IBusinessDependencies
实例持久化到 ivar 或其他东西。每次需要使用时,您都需要将其从服务集合中拉出。
我必须进行服务/数据库调用才能根据请求声明映射 UserId。通常,我会像这样简单地做到这一点:
public class AuthUserIdProvider : IUserIdProvider
{
private IBusinessDependencies Dependencies { get; }
public AuthUserIdProvider(IBusinessDependencies dependencies)
{
Dependencies = dependencies;
}
public string GetUserId(HubConnectionContext connection)
{
var email = connection.User.Claims.FirstOrDefault(m => m.Type.Equals(ClaimTypes.Email, StringComparison.OrdinalIgnoreCase))?.Value;
if (string.IsNullOrEmpty(email))
{
return null;
}
return Dependencies.EntityServices.UserService.GetUserByEmailCached(email).GetAwaiter().GetResult().Id.ToString();
}
}
但是 IBusinessDependencies
是有范围的,因为有一堆业务逻辑取决于特定的请求/会话。
是否可以将 IUserIdProvider
注册为作用域而不是单例?或者也许还有其他更好的解决方案?
我个人从来不需要使用 IUserIdProvider
,但我看不到任何特别 要求 它是单例的。不过,我可能错过了一些东西。但是,我想您在来这里之前至少必须尝试将其注册为作用域(希望如此)。
假设它必须是单例,那么你唯一的选择就是 service-locator 模式。不是注入 IBusinessDependencies
,而是注入 IServiceProvider
。然后每当你真正需要你的 IBusinessDependencies
实例时:
using (var scope = _serviceProvider.CreateScope())
{
var dependencies = scope.ServiceProvider.GetRequiredService<IBusinessDependencies>();
// do something with dependencies
}
如果不明显,您不能将 IBusinessDependencies
实例持久化到 ivar 或其他东西。每次需要使用时,您都需要将其从服务集合中拉出。