AyCode.Core/AyCode.Services/SignalRs/AcSignalRProtocolExtensions.cs

51 lines
2.1 KiB
C#

using Microsoft.AspNetCore.SignalR.Client;
using Microsoft.AspNetCore.SignalR.Protocol;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
namespace AyCode.Services.SignalRs;
/// <summary>
/// Client-side registration extension for the <see cref="AyCodeBinaryHubProtocol"/> (<c>"acbinary"</c>).
/// Mirrors the ASP.NET Core idiomatic pattern of <c>AddJsonProtocol(...)</c> /
/// <c>AddMessagePackProtocol(...)</c>.
/// <para>
/// For the server-side equivalent see <c>AcSignalRServerProtocolExtensions</c> in
/// <c>AyCode.Services.Server</c> — kept separate to avoid dragging the server SignalR assembly
/// (<c>Microsoft.AspNetCore.SignalR.Core</c>) into pure client projects (MAUI, WASM).
/// </para>
/// </summary>
public static class AcSignalRProtocolExtensions
{
/// <summary>
/// Registers <see cref="AyCodeBinaryHubProtocol"/> as the protocol for a client <see cref="HubConnection"/>.
/// Call on the <see cref="IHubConnectionBuilder"/> during client setup.
/// </summary>
public static IHubConnectionBuilder AddAcBinaryProtocol(this IHubConnectionBuilder builder, Action<AcBinaryHubProtocolOptions>? configure = null)
{
builder.Services.AddSingleton<IHubProtocol>(sp => BuildProtocol(sp, configure));
return builder;
}
/// <summary>
/// Shared factory used by both client (this file) and server
/// (<c>AcSignalRServerProtocolExtensions</c> in AyCode.Services.Server).
/// Resolves options from DI (<c>IOptions&lt;T&gt;</c>), clones them, applies the inline
/// <paramref name="configure"/> override, validates, and constructs the protocol.
/// </summary>
public static IHubProtocol BuildProtocol(IServiceProvider sp, Action<AcBinaryHubProtocolOptions>? configure)
{
var diOptions = sp.GetService<IOptions<AcBinaryHubProtocolOptions>>()?.Value;
var options = diOptions?.Clone() ?? new AcBinaryHubProtocolOptions();
options.Logger ??= sp.GetService<ILogger<AcBinaryHubProtocol>>();
configure?.Invoke(options);
options.Validate();
return new AyCodeBinaryHubProtocol(options);
}
}