[英]Dependency Injection into SignalR Hub (dotnet core 3.1)
我正在使用 SignalR 並且在讓 DI 進入 SignalR 集線器時遇到問題。 我以為它會使用現有的 dotnet core DI 框架,但似乎並非如此。 我不斷得到
System.InvalidOperationException: Unable to resolve service for type 'Comcast.Cs.Mercury.Web.Api.IHubClientHelper' while attempting to activate 'mercury_ms_auth.Hubs.AuthenticationHub'.
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)
我注冊了 singleton:
services.AddSingleton<IHubClientHelper>(new HubClientHelper(loggerFactory.CreateLogger<HubClientHelper>())
{
ClientConnectionType = _environment.IsDevelopment()
? ClientConnectionType.ConnectionId
: ClientConnectionType.UserId
});
而且我有依賴進入集線器的構造函數:
public AuthenticationHub(TelemetryClient telemetryClient, IHubClientHelper clientHelper)
: base(telemetryClient, clientHelper)
{
}
文檔表明這應該有效。 有任何想法嗎?
您的問題不是很清楚,但我將嘗試回答您如何正確注冊集線器並使用 DI 注入它。 首先,您在啟動時添加集線器:
services.AddSignalR(hubOptions =>
{
hubOptions.ClientTimeoutInterval = TimeSpan.FromSeconds(hostConfiguration.SignalR.ClientTimeoutInterval);
hubOptions.HandshakeTimeout = TimeSpan.FromSeconds(hostConfiguration.SignalR.HandshakeTimeout);
hubOptions.KeepAliveInterval = TimeSpan.FromSeconds(hostConfiguration.SignalR.KeepAliveInterval);
hubOptions.EnableDetailedErrors = hostConfiguration.SignalR.EnableDetailedErrors;
hubOptions.MaximumReceiveMessageSize = hostConfiguration.SignalR.MaximumReceiveMessageSize;
hubOptions.StreamBufferCapacity = hostConfiguration.SignalR.StreamBufferCapacity;
});
app.UseSignalR(routes =>
{
routes.MapHub<YourHub>(/yourHub);
});
因此,這會將您的集線器添加為transient
。 然后你可以像這樣注入你的集線器:
private IHubContext<YourHub, IYourHub> YourHub
{
get
{
return this.serviceProvider.GetRequiredService<IHubContext<YourHub, IYourHub>>();
}
}
還有一些注意事項:
SignalR 期望為每條消息單獨創建集線器。 如果您希望集線器處於 DI 中,則需要將其添加為瞬態服務。 您通常不應該將集線器從 DI 中解析出來。 如果您需要在 Hub 和其他一些組件之間共享代碼,我建議使用 IHubContext 或將共享代碼放在單獨的 DI 服務中。
發現了問題。 我正在使用 Unity Container,結果發現該容器沒有像 OOTB DI 框架那樣自動注冊 ILogger。 我通過使用 Immediate Window 嘗試解決 IHubClientHelper 發現了這一點,它最終告訴我它無法解析 ILogger ( No public constructor is available for type Microsoft.Extensions.Logging.ILogger.
)。 在快速谷歌之后,我找到了這個,並通過將以下內容添加到 Startup.cs 中的 ConfigureContainer 方法,我再次啟動並運行。
var logFactory = new LoggerFactory();
container.AddExtension(new LoggingExtension(logFactory));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.