Search code examples
c#blazorblazor-server-sidemediatr

Blazor Server and MediatR - component's properties are `null` when handling notification


I'm building a Blazor Server app that has an API alongside it and want to do live update in the UI when someone accesses the API, store in the DB and update the UI.

For the notifications I've opted for the Mediator which is source-generated alternative to the MediatR.

There are no issues with controller and storing the data in database. The issue is with the Blazor component.

So, I have a simple notification:

public sealed class UserConnected : INotification
{
    public required User User { get; init; }
}

and Blazor component implementing the INotificationHandler<UserConnected>:

public partial class ManageUsers : ComponentBase, INotificationHandler<PagerConnected>
{
    private List<User> users = new();

    [Inject]
    private ApplicationDbContext Context { get; set; } = default!;

    // Update UI when User connects
    public async ValueTask Handle(UserConnected notification, CancellationToken cancellationToken)
        => await UpdateUsers().ConfigureAwait(false);

    private async Task UpdateUsers()
    {
        users = await Context.Users
            .Include(x => x.ApiKey)
            .ToListAsync()
            .ConfigureAwait(false);
    }
}

The thing is that when the Handle method is invoked by Mediator, the Context propperty is null and thus I get the NullReferenceException.

I believe this might be due to the Mediator using a reflection (?), but I have have no idea how could I fix this problem.

Thank you in advance


Solution

  • Blazor components cannot be MediatR notification handlers.

    The .AddServices() extension method registers the handlers as Transient, which creates a new instance of the class to handle the notification. That means the one that is being used in rendering is not the same instance as the one that is handling the notification. In order to share data between the handlers and the Razor components you will need a shared dependency that both can interact with.

    Check this GitHub issue.