Skip to content

Commit d5f8387

Browse files
committed
Refactor HubClient with factory pattern
Refactored the `HubClient` class to use a new `IHubConnectionFactory` interface for creating `HubConnection` instances, improving separation of concerns and testability. Updated `DependencyInjection.cs` to register `IHubConnectionFactory` and `HubClient` with the DI container. Introduced `IHubConnectionFactory` and its implementation `HubConnectionFactory` to handle connection creation logic, utilizing `NavigationManager` and `IHttpContextAccessor` for configuration.
1 parent aea7e20 commit d5f8387

File tree

3 files changed

+55
-22
lines changed

3 files changed

+55
-22
lines changed

src/Server.UI/DependencyInjection.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,8 @@ public static IServiceCollection AddServerUI(this IServiceCollection services, I
9696
c.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
9797
});
9898
services.AddScoped<LocalTimeOffset>();
99-
services.AddScoped<HubClient>();
99+
services.AddScoped<IHubConnectionFactory, HubConnectionFactory>()
100+
.AddScoped<HubClient>();
100101
services
101102
.AddScoped<AuthenticationStateProvider, IdentityRevalidatingAuthenticationStateProvider>()
102103
.AddScoped<LayoutService>()

src/Server.UI/Hubs/HubClient.cs

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -9,29 +9,10 @@ public sealed class HubClient : IAsyncDisposable
99
{
1010
private readonly HubConnection _hubConnection;
1111
private bool _started;
12-
public HubClient(NavigationManager navigationManager, IHttpContextAccessor httpContextAccessor)
12+
public HubClient(IHubConnectionFactory hubConnectionFactory)
1313
{
14-
var uri = new UriBuilder(navigationManager.Uri);
15-
var container = new CookieContainer();
16-
if (httpContextAccessor.HttpContext != null)
17-
{
18-
foreach (var c in httpContextAccessor.HttpContext.Request.Cookies)
19-
{
20-
container.Add(new Cookie(c.Key, c.Value)
21-
{
22-
Domain = uri.Host,
23-
Path = "/"
24-
});
25-
}
26-
}
2714

28-
var hubUrl = navigationManager.BaseUri.TrimEnd('/') + ISignalRHub.Url;
29-
_hubConnection = new HubConnectionBuilder()
30-
.WithUrl(hubUrl, options =>
31-
{
32-
options.Transports = HttpTransportType.WebSockets;
33-
options.Cookies = container;
34-
}).WithAutomaticReconnect().Build();
15+
_hubConnection = hubConnectionFactory.CreateForCurrentUser(ISignalRHub.Url);
3516

3617
_hubConnection.ServerTimeout = TimeSpan.FromSeconds(20);
3718
_hubConnection.KeepAliveInterval = TimeSpan.FromSeconds(10);
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
using System.Net;
2+
using Microsoft.AspNetCore.Http.Connections;
3+
using Microsoft.AspNetCore.SignalR.Client;
4+
5+
namespace CleanArchitecture.Blazor.Server.UI.Hubs;
6+
7+
public interface IHubConnectionFactory
8+
{
9+
HubConnection CreateForCurrentUser(string relativeHubUrl);
10+
}
11+
public class HubConnectionFactory : IHubConnectionFactory
12+
{
13+
private readonly NavigationManager _navigationManager;
14+
private readonly IHttpContextAccessor _httpContextAccessor;
15+
16+
public HubConnectionFactory(
17+
NavigationManager navigationManager,
18+
IHttpContextAccessor httpContextAccessor)
19+
{
20+
_navigationManager = navigationManager;
21+
_httpContextAccessor = httpContextAccessor;
22+
}
23+
24+
public HubConnection CreateForCurrentUser(string relativeHubUrl)
25+
{
26+
var uri = new UriBuilder(_navigationManager.Uri);
27+
var container = new CookieContainer();
28+
29+
var httpContext = _httpContextAccessor.HttpContext;
30+
if (httpContext != null &&
31+
httpContext.Request.Cookies.TryGetValue(".AspNetCore.Identity.Application", out var authCookie))
32+
{
33+
container.Add(new Cookie(".AspNetCore.Identity.Application", authCookie)
34+
{
35+
Domain = uri.Host,
36+
Path = "/"
37+
});
38+
}
39+
40+
var hubUrl = _navigationManager.BaseUri.TrimEnd('/') + relativeHubUrl;
41+
42+
return new HubConnectionBuilder()
43+
.WithUrl(hubUrl, options =>
44+
{
45+
options.Transports = HttpTransportType.WebSockets;
46+
options.Cookies = container;
47+
})
48+
.WithAutomaticReconnect()
49+
.Build();
50+
}
51+
}

0 commit comments

Comments
 (0)