dotnet-cqrs/Svrnty.CQRS.Events.SignalR/ServiceCollectionExtensions.cs

156 lines
5.4 KiB
C#

using System;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
namespace Svrnty.CQRS.Events.SignalR;
/// <summary>
/// Extension methods for registering SignalR event streaming services.
/// </summary>
public static class ServiceCollectionExtensions
{
/// <summary>
/// Adds SignalR-based real-time event streaming to the service collection.
/// </summary>
/// <param name="services">The service collection.</param>
/// <returns>The service collection for method chaining.</returns>
/// <remarks>
/// <para>
/// This registers the EventStreamHub and enables real-time event push to browser clients.
/// Clients can connect via SignalR and subscribe to event streams.
/// </para>
/// <para>
/// <strong>Prerequisites:</strong>
/// - Call <c>services.AddSignalR()</c> first to register SignalR core services
/// - Event streaming must be configured via <c>AddSvrntyEvents()</c>
/// </para>
/// </remarks>
/// <example>
/// <code>
/// var builder = WebApplication.CreateBuilder(args);
///
/// // Register SignalR and event streaming
/// builder.Services.AddSignalR();
/// builder.Services.AddSvrntyEvents();
/// builder.Services.AddEventStreamHub(); // Enable SignalR event streaming
///
/// var app = builder.Build();
///
/// // Map the hub endpoint
/// app.MapHub&lt;EventStreamHub&gt;("/hubs/events");
///
/// app.Run();
/// </code>
/// </example>
public static IServiceCollection AddEventStreamHub(this IServiceCollection services)
{
if (services == null)
throw new ArgumentNullException(nameof(services));
// EventStreamHub is automatically registered by SignalR when mapped
// No explicit registration needed here
return services;
}
/// <summary>
/// Maps the EventStreamHub to the specified endpoint.
/// </summary>
/// <param name="app">The web application.</param>
/// <param name="pattern">The URL pattern for the hub endpoint (default: "/hubs/events").</param>
/// <returns>The web application for method chaining.</returns>
/// <example>
/// <code>
/// app.MapEventStreamHub(); // Maps to /hubs/events
/// app.MapEventStreamHub("/api/events"); // Custom endpoint
/// </code>
/// </example>
public static WebApplication MapEventStreamHub(
this WebApplication app,
string pattern = "/hubs/events")
{
if (app == null)
throw new ArgumentNullException(nameof(app));
if (string.IsNullOrWhiteSpace(pattern))
throw new ArgumentException("Pattern cannot be null or empty", nameof(pattern));
app.MapHub<EventStreamHub>(pattern);
return app;
}
/// <summary>
/// Adds persistent subscription support via SignalR to the service collection.
/// </summary>
/// <param name="services">The service collection.</param>
/// <returns>The service collection for method chaining.</returns>
/// <remarks>
/// <para>
/// This registers the PersistentSubscriptionHub for correlation-based event subscriptions
/// that persist across disconnections and support selective event filtering.
/// </para>
/// <para>
/// <strong>Prerequisites:</strong>
/// - Call <c>services.AddSignalR()</c> first to register SignalR core services
/// - Call <c>services.AddPersistentSubscriptions()</c> to register subscription infrastructure
/// - Event streaming must be configured via <c>AddSvrntyEvents()</c>
/// </para>
/// </remarks>
/// <example>
/// <code>
/// var builder = WebApplication.CreateBuilder(args);
///
/// // Register services
/// builder.Services.AddSignalR();
/// builder.Services.AddSvrntyEvents();
/// builder.Services.AddPersistentSubscriptions();
/// builder.Services.AddPersistentSubscriptionHub();
///
/// var app = builder.Build();
///
/// // Map the hub endpoint
/// app.MapPersistentSubscriptionHub("/hubs/subscriptions");
///
/// app.Run();
/// </code>
/// </example>
public static IServiceCollection AddPersistentSubscriptionHub(this IServiceCollection services)
{
if (services == null)
throw new ArgumentNullException(nameof(services));
// PersistentSubscriptionHub is automatically registered by SignalR when mapped
// No explicit registration needed here
return services;
}
/// <summary>
/// Maps the PersistentSubscriptionHub to the specified endpoint.
/// </summary>
/// <param name="app">The web application.</param>
/// <param name="pattern">The URL pattern for the hub endpoint (default: "/hubs/subscriptions").</param>
/// <returns>The web application for method chaining.</returns>
/// <example>
/// <code>
/// app.MapPersistentSubscriptionHub(); // Maps to /hubs/subscriptions
/// app.MapPersistentSubscriptionHub("/api/subscriptions"); // Custom endpoint
/// </code>
/// </example>
public static WebApplication MapPersistentSubscriptionHub(
this WebApplication app,
string pattern = "/hubs/subscriptions")
{
if (app == null)
throw new ArgumentNullException(nameof(app));
if (string.IsNullOrWhiteSpace(pattern))
throw new ArgumentException("Pattern cannot be null or empty", nameof(pattern));
app.MapHub<PersistentSubscriptionHub>(pattern);
return app;
}
}