ASP.NET Core SignalR替换GlobalHost.DependencyResolver及相关适配问题咨询
1、ASP.NET Core SignalR中GlobalHost.DependencyResolver的替代方案
ASP.NET Core SignalR 已经完全移除了GlobalHost静态类,原有两个核心能力的替代方案如下:
- 给SignalR指定DI容器:不再需要单独配置Resolver,直接使用ASP.NET Core的DI注册体系即可,所有SignalR相关服务、Hub依赖都会自动从全局DI容器解析
- 全局获取Hub上下文操作:需要主动给客户端发消息等场景,在业务类中注入
IHubContext<你定义的Hub类>即可获取对应Hub的上下文实例
2、保留Unity作为DI容器的配置方法
不需要使用内置DI组件,直接替换默认服务提供器为Unity即可,步骤如下:
- 安装适配.NET 5版本的NuGet包:
Unity.Microsoft.DependencyInjection - 修改
Program.cs的Host构建逻辑,指定使用Unity服务提供器,同时注入你原有容器的注册规则:
public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) // 替换默认服务提供器为Unity .UseUnityServiceProvider() // 配置Unity容器,加入原有注册逻辑 .ConfigureContainer<IUnityContainer>(container => { var unityConfiguration = new UnityConfiguration(); unityConfiguration.RegisterTypes(container); }) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); });
配置完成后,包括SignalR Hub在内的所有服务依赖都会从Unity容器解析,完全替代原有UnityDependencyResolver的作用。
3、HubPipelineModule的替代实现方案
ASP.NET Core SignalR使用Hub过滤器(IHubFilter接口) 实现原有HubPipelineModule的拦截能力,支持在Hub方法执行前后、连接建立/断开时插入自定义逻辑,和原有逻辑完全对齐:
- 实现自定义过滤器,以你原有
SessionIdCheckModule为例:
public class SessionIdCheckFilter : IHubFilter { // 拦截Hub方法调用 public async ValueTask<object> InvokeMethodAsync(HubInvocationContext invocationContext, Func<HubInvocationContext, ValueTask<object>> next) { // 此处放入原HubPipelineModule的OnBeforeIncoming逻辑,例如SessionId校验 if (!ValidateSessionId(invocationContext.Context.GetHttpContext())) { throw new UnauthorizedAccessException("SessionId无效"); } // 执行后续Hub逻辑 var result = await next(invocationContext); // 此处放入原HubPipelineModule的OnAfterIncoming逻辑 return result; } // 拦截连接建立事件 public async Task OnConnectedAsync(HubLifetimeContext context, Func<HubLifetimeContext, Task> next) { // 自定义连接建立逻辑 await next(context); } // 拦截连接断开事件 public async Task OnDisconnectedAsync(HubLifetimeContext context, Exception exception, Func<HubLifetimeContext, Exception, Task> next) { // 自定义连接断开逻辑 await next(context, exception); } private bool ValidateSessionId(HttpContext context) { // 你的校验逻辑 return true; } }
- 在
Startup.cs的ConfigureServices方法中注册全局过滤器即可全局生效:
public void ConfigureServices(IServiceCollection services) { services.AddSignalR(options => { // 你原有禁用其他传输协议仅保留长轮询的逻辑,直接在这里配置即可,不需要单独写方法 options.Transports = HttpTransportType.LongPolling; }) // 注册自定义Hub过滤器 .AddHubFilter<SessionIdCheckFilter>(); // 其他服务注册 }
如果需要只给特定Hub启用过滤器,也可以在注册Hub路由时单独指定,灵活性高于原有HubPipelineModule。
内容的提问来源于stack exchange,提问作者Dhiren Bhatia
相关产品推荐
相关产品推荐

