Skip to content



Event handlers are just like commands, but they are used to notify other parts of the application that something has happened.
Events are not meant to return a value, but rather to notify other parts of the application that something has happened.

Shiny Mediator does a couple of other cool things that other Mediator libraries do not.

  • They support middleware, which allows you to intercept and modify events before they are processed. This is useful for things like logging, error handling, and more.
  • Event collectors allow you to publish events to other temporary sources such as a transient/scoped viewmodel attached to a .NET MAUI page or Blazor component that may not be registered with your dependency container.

Publishing events are done through the IMediator interface. You can publish events in a fire-and-forget manner or wait for them to complete.

  1. Just like with requests, let’s setup our event and event handler

    public class TestEvent : IEvent {}
    public class TestEventHandler : IEventHandler<TestEvent>
    public Task Handle(TestEvent @event, CancellationToken ct) => Task.CompletedTask;
  2. Now let’s publish our event

    IMediator mediator; // get from your DI container or inject into your DI aware component
    await mediator.Publish(new TestEvent());
  3. Don’t want to wait around for all your events to finish. We have an easy fire & forget set of methods.

    mediator.Publish(new TestEvent()).RunInBackground(error => {});


If your page or viewmodel implements the IEventHandler interface, it will automatically participate in the event chain. If the page is popped off the navigation stack, it is no longer part of the event chain.

To add .NET MAUI support:

  1. Install the Shiny.Mediator.Maui package

    Terminal window
    dotnet add package Shiny.Mediator.Maui
  2. Now, in your MauiProgram.cs, alter the AddShinyMediator call

    builder.Services.AddShinyMediator(cfg => cfg.UseMaui());

Blazor (& Blazor MAUI Hyrbid)

Blazor is a bit of a different beast vs .NET MAUI since their isn’t a navigation stack, there is really only a single active page. Any component in Blazor, can implement IEventHandler to catch an event.

  1. Install the Shiny.Mediator.Blazor package

    Terminal window
    dotnet add package Shiny.Mediator.Blazor
  2. Now, in your Startup.cs, alter the AddShinyMediator call

    services.AddShinyMediator(cfg => cfg.UseBlazor());


Event middleware is far simpler than request & streaming middleware due to no results being returned by the handler. Like all other middleware, covariance is supported so you can intercept a base event and modify it before it is processed.

Below is a super simple example of an exception handler middleware that uses convariance to work against all event types.

public class ExceptionHandlerEventMiddleware<TEvent>(ILogger<TEvent> logger) : IEventMiddleware<TEvent> where TEvent : IEvent
public async Task Process(IEvent @event, EventHandlerDelegate next, IEventHandler<TEvent> eventHandler, CancellationToken cancellationToken)
await next().ConfigureAwait(false);
catch (Exception ex)
logger.LogError(ex, $"Error in event {@event.GetType().FullName}");

To register an event like this:

ServiceCollection service; // with your host builder or service collection
services.AddShinyMediator(cfg =>
// NOTE: the open generic