SignalRGen 1.0.0-alpha.1

This is a prerelease version of SignalRGen.
dotnet add package SignalRGen --version 1.0.0-alpha.1
                    
NuGet\Install-Package SignalRGen -Version 1.0.0-alpha.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="SignalRGen" Version="1.0.0-alpha.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="SignalRGen" Version="1.0.0-alpha.1" />
                    
Directory.Packages.props
<PackageReference Include="SignalRGen" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add SignalRGen --version 1.0.0-alpha.1
                    
#r "nuget: SignalRGen, 1.0.0-alpha.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#addin nuget:?package=SignalRGen&version=1.0.0-alpha.1&prerelease
                    
Install SignalRGen as a Cake Addin
#tool nuget:?package=SignalRGen&version=1.0.0-alpha.1&prerelease
                    
Install SignalRGen as a Cake Tool

.Net

A source-generator-based approach to easily setup SignalR communication

Purpose

SignalR is an amazing tech to implement asynchronous communication, but to get it up and running you will write a bunch of boilerplate-code. SignalRGen will take the boilerplate off your shoulders and allows easy integration of your Hubs inside your client/s.

With SignalRGen you can easily share your SignalR client easily with a nice developer experience to integrate with.

Installation

SignalRGen is published as a nuget package, you can install it with:

dotnet add package SignalRGen

There are also YOLO packages pushed here in this GitHub repository.

Setup

You describe your SignalR client with an interface and add the HubClientAttribute (this is in the namespace SignalRGen.Generator) to it.

Example:

using SignalRGen.Generator;

namespace SignalRGen.Example.Contracts;

[HubClient(HubUri = "examples")]
public interface IExampleHubClient
{
    Task ReceiveExampleCountUpdate(int count);
}

In the example above, you see a simple client description that has one simple method that will be translated into a client method. Notice the HubUri that is set inside the HubClient attribute. With this, you can define on which route your hub is listening on. Also notice that your method should return a Task.

By doing that SignalRGen will use source generation to pick up your interface via the HubClientAttribute and generate the necessary boilerplate for you.

Server-Side usage

After you did the setup part, you can register your Hub like this to point to the correct Uri:

var app = builder.Build();

app.MapHub<ExampleHub>($"/{ExampleHubClient.HubUri}");

Apart from that SignalRGen currently doesn't do anything for the server experience.

Client-Side usage

After you have done the setup part, you will have a greatly enhanced client experience. SignalRGen generates multiple files, like, for example, this client:

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
using Microsoft.AspNetCore.SignalR.Client;
using SignalRGen.Generator;

#nullable enable
namespace SignalRGen.Generator;
/// <summary>
/// Represents a HubClient for the <see cref = "IExampleHubClient"/> interface.
/// </summary>
public class ExampleHubClient : HubClientBase, IHubClient
{
    public static string HubUri { get; } = "examples";

    public ExampleHubClient(IHubConnectionBuilder hubConnectionBuilder) : base(hubConnectionBuilder)
    {
    }

    /// <summary>
    /// Is invoked whenever the client method ReceiveExampleCountUpdate of the <see cref = "IExampleHubClient"/> gets invoked.
    /// </summary>
    public Func<int, Task>? OnReceiveExampleCountUpdate = default;
    private Task ReceiveExampleCountUpdateHandler(int count)
    {
        return OnReceiveExampleCountUpdate?.Invoke(count) ?? Task.CompletedTask;
    }

    protected override void RegisterHubMethods()
    {
        _hubConnection.On<int>("ReceiveExampleCountUpdate", ReceiveExampleCountUpdateHandler);
    }
}

The important part for usage is the public Func<int, Task>? OnReceiveExampleCountUpdate = default;. This is the Func you have to subscribe to to get notified when the server triggers this SignalR method.

SignalRGen will also generate extension methods to register everything on the client. Our example above can be registered like this:

using SignalRGen.Generator.Client.Extensions.DependencyInjection;

var builder = WebApplication.CreateBuilder(args);

builder.Services
    .AddSignalRHubs(c => c.HubBaseUri = new Uri("http://localhost:5155"))
    .WithExampleHubClient();

You will have one global entrypoint with AddSignalRHubs() where you can configure the server to talk to. For each Hub you will have a WithXYZ method to add the XYZ Hub to the dependency injection container as a Singleton by default. With these you can also configure your Hub the way you like:

using SignalRGen.Generator.Client.Extensions.DependencyInjection;

var builder = WebApplication.CreateBuilder(args);

builder.Services
    .AddSignalRHubs(c => c.HubBaseUri = new Uri("http://localhost:5155"))
    .WithExampleHubClient(options =>
    {
        options.HubClientLifetime = ServiceLifetime.Scoped;
        options.HubConnectionBuilderConfiguration = connectionBuilder =>
            connectionBuilder.WithAutomaticReconnect();
    });

After setting up your DI like described above you can use the ExampleHubClient like so (Blazor example code):

@page "/"
@using SignalRGen.Generator

@inject ExampleHubClient ExampleHubClient;

<h1>Hello, world!</h1>

<p>Current count received via SignalRClient generated by SignalRGen: @_count</p>

@code
{
    private int _count = 0;
    
    protected override async Task OnInitializedAsync()
    {
        ExampleHubClient.OnReceiveExampleCountUpdate += OnReceiveExampleCountUpdate;
        await ExampleHubClient.StartAsync();
    }

    private async Task OnReceiveExampleCountUpdate(int arg)
    {
        _count = arg;
        await InvokeAsync(StateHasChanged);
    }
}

The ExampleHubClient.StartAsync() can be called multiple times, as it checks if the connection is not disconnected and only starts it if the HubConnectionState is disconnected. So multiple calls will not start the connection multiple times.

If you want to get a deeper understanding and look at the generated code, head over to the wiki here on GitHub.

Recognitions

This library wouldn't have been possible if not for the following people (please note: the order is completely random):

There are no supported framework assets in this package.

Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.0.0-alpha.1 110 5/22/2025