我必须进行服务/数据库调用,以便根据请求声明映射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
注册为作用域而不是单例?也许还有另一个更好的解决方案?
答案 0 :(得分:1)
我从不需要亲自使用IUserIdProvider
,但是我看不到任何要求为单例的东西。不过,我可能错过了一些东西。但是,我想您必须(至少希望)在到达这里之前至少尝试将其注册为作用域。
假设它必须是一个单例,那么您唯一的选择是服务定位器模式。而不是注入IBusinessDependencies
,而是注入IServiceProvider
。然后,每当您实际需要您的IBusinessDependencies
实例时,请执行以下操作:
using (var scope = _serviceProvider.CreateScope())
{
var dependencies = scope.ServiceProvider.GetRequiredService<IBusinessDependencies>();
// do something with dependencies
}
如果情况不太明显,则不能将IBusinessDependencies
实例持久化到ivar或其他对象。每次需要使用它时,都需要将其从服务集合中拉出。