【问题标题】:Unable to resolve service for type 'Microsoft.AspNetCore.SignalR.Hub`1[IXXXX]' while attempting to activate 'XXXXX'尝试激活“XXXXX”时无法解析“Microsoft.AspNetCore.SignalR.Hub`1[IXXXX]”类型的服务
【发布时间】:2023-03-06 21:26:02
【问题描述】:

我完全按照 MS 规则定义了我的强类型 SignalR 集线器

public class OutputMessages : Hub<IOutputMessages>
{...}

以同样的方式将我的 SignalR 集线器注入到控制器

public class ApplicationAPIController : ControllerBase
{
     public ApplicationAPIController(IHubContext<OutputMessages, IOutputMessages> _outputMessages)
     {...}
}

在启动中我将 SignalR 服务添加为

        services.AddSignalR()
                .AddHubOptions<OutputMessages>(options =>
                {
                    options.EnableDetailedErrors = true;
                })

并定义端点

        app.UseEndpoints(endpoints =>
            {
                endpoints.MapHub<OutputMessages>("/OutputMessages", options =>
                {
                   options.Transports =
                   HttpTransportType.WebSockets |
                   HttpTransportType.LongPolling;
                });

           });

看起来不错?是的。而且编译很好。但在运行时我收到

fail: Microsoft.AspNetCore.SignalR.HubConnectionHandler[1]
      Error when dispatching 'OnConnectedAsync' on hub.
System.InvalidOperationException: Unable to resolve service for type 'Microsoft.AspNetCore.SignalR.Hub`1[IOutputMessages]' while attempting to activate 'OutputMessages'.
   at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetService(IServiceProvider sp, Type type, Type requiredBy, Boolean isDefaultParameterRequired)
   at lambda_method(Closure , IServiceProvider , Object[] )
   at Microsoft.AspNetCore.SignalR.Internal.DefaultHubActivator`1.Create()
   at Microsoft.AspNetCore.SignalR.Internal.DefaultHubDispatcher`1.OnConnectedAsync(HubConnectionContext connection)
   at Microsoft.AspNetCore.SignalR.Internal.DefaultHubDispatcher`1.OnConnectedAsync(HubConnectionContext connection)
   at Microsoft.AspNetCore.SignalR.HubConnectionHandler`1.RunHubAsync(HubConnectionContext connection)
dbug: Microsoft.AspNetCore.SignalR.HubConnectionHandler[6]
      OnConnectedAsync ending.

【问题讨论】:

  • 我不认为.AddHubOptions&lt;OutputMessages&gt;(options =&gt;... 是正确的。将其更改为services.AddSignalR(o =&gt; o.EnableDetailedErrors = true);,然后尝试注入IOutputMessages 正常路线:services.AddTransient&lt;IOutputMessages, OutputMessages&gt;();
  • 在这种情况下,我在项目初始化中收到 - '某些服务无法构建(验证服务描述符时出错'ServiceType:IOutputMessages Lifetime:Transient ImplementationType:OutputMessages':无法解析服务在尝试激活“OutputMessages”时键入“Microsoft.AspNetCore.SignalR.Hub`1[IOutputMessages]”。)”
  • 问题是你的集线器方法中有一个构造函数到你的OutputMessages 类。您不需要任何构造函数,因为AddSignalR 在 DI 上注册了 HUB。然后,您通过 DI 解决的依赖关系就像我在之前的问题中回答的那样。

标签: asp.net-core dependency-injection signalr


【解决方案1】:

终于找到了解决办法

这是我的强类型集线器定义

public class OutputMessages : Hub<IOutputMessages>
        {
            public static readonly Dictionary<string, string> ConnectedUserList = new Dictionary<string, string>(1024);
            private readonly IHubContext<OutputMessages,IOutputMessages> _hubContext;
            private readonly ApplicationDbContext _db;
            private readonly ILogger<OutputMessages> _logger;

        public OutputMessages(IHubContext<OutputMessages, IOutputMessages> hubContext, ILogger<OutputMessages> logger, ApplicationDbContext dbContext)
        {
            _hubContext = hubContext;
            _db = dbContext;
            _logger = logger;
        }

....

        public async Task AdminMessages2(string userId, string message, bool consoleOnly)
        {
            string uname = await Username(userId);
            await _hubContext.Clients.All.AdminMessages2(userId, "API: " + uname + " " + message, consoleOnly);
        }

        [ResponseCache(VaryByHeader = "id", Duration = 36000, Location = ResponseCacheLocation.Any)]
        public async Task<string> Username(string id)
        {
            ApplicationUser user = null;
            await Task.Run(() => user = _db.Users.Find(id));
            return user.UserName;
        }

        public override async Task OnConnectedAsync()
        {
            string JWT = Context.GetHttpContext().Request.Headers["Authorization"];
            string ValidUserID = UserHelpers.ValidateJWT(JWT);
            if (ValidUserID != null)
            {
                _logger.LogInformation($"User {ValidUserID} connected to {this.GetType().Name} hub");
                if (ConnectedUserList.Any(x => x.Key == ValidUserID))
                {
                    ConnectedUserList.Remove(ValidUserID);
                }
                ConnectedUserList.Add(ValidUserID, Context.ConnectionId);
            }
            await base.OnConnectedAsync();
        }

        public override async Task OnDisconnectedAsync(System.Exception exception)
        {
            var JWT = Context.GetHttpContext().Request.Headers["Authorization"];
            string ValidUserID = UserHelpers.ValidateJWT(JWT);
            if (ValidUserID != null)
            {
                _logger.LogInformation($"User {ValidUserID} disconnected from {this.GetType().Name} hub");
                if (ConnectedUserList.Any(x => x.Key == ValidUserID))
                {
                    ConnectedUserList.Remove(ValidUserID);
                }
                ConnectedUserList.Add(ValidUserID, Context.ConnectionId);
            }
            await base.OnDisconnectedAsync(exception);
        }
    }

这是控制器的注入集线器

    public class ApplicationAPIController : ControllerBase
    {
         public ApplicationAPIController(ILogger<ApplicationAPIController> logger, ApplicationDbContext dbContext, IConfiguration Configuration, CoreObjectDumper.CoreObjectDumper dump, IHubContext<OutputMessages, IOutputMessages> _outputMessages)
        {
 ...

StartUp 中 SignalR 服务的定义未更改。问题是从类而不是接口创建 Hub,并且 Hub 构造函数必须完全是 IHubContext

【讨论】:

    猜你喜欢
    • 2018-04-06
    • 2021-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-23
    • 1970-01-01
    相关资源
    最近更新 更多