SignalR:对IUserIdProvider使用范围服务

时间:2019-05-17 14:14:59

标签: signalr asp.net-core-signalr

我必须进行服务/数据库调用,以便根据请求声明映射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注册为作用域而不是单例?也许还有另一个更好的解决方案?

1 个答案:

答案 0 :(得分:1)

我从不需要亲自使用IUserIdProvider,但是我看不到任何要求为单例的东西。不过,我可能错过了一些东西。但是,我想您必须(至少希望)在到达这里之前至少尝试将其注册为作用域。

假设它必须是一个单例,那么您唯一的选择是服务定位器模式。而不是注入IBusinessDependencies,而是注入IServiceProvider。然后,每当您实际需要您的IBusinessDependencies实例时,请执行以下操作:

using (var scope = _serviceProvider.CreateScope())
{
    var dependencies = scope.ServiceProvider.GetRequiredService<IBusinessDependencies>();
    // do something with dependencies
}

如果情况不太明显,则不能将IBusinessDependencies实例持久化到ivar或其他对象。每次需要使用它时,都需要将其从服务集合中拉出。