Events
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.
-
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;} -
Now let’s publish our event
IMediator mediator; // get from your DI container or inject into your DI aware componentawait mediator.Publish(new TestEvent()); -
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 => {});
.NET MAUI
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:
-
Install the
Shiny.Mediator.Maui
packageTerminal window dotnet add package Shiny.Mediator.Maui -
Now, in your
MauiProgram.cs
, alter theAddShinyMediator
callbuilder.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.
-
Install the
Shiny.Mediator.Blazor
packageTerminal window dotnet add package Shiny.Mediator.Blazor -
Now, in your
Startup.cs
, alter theAddShinyMediator
callservices.AddShinyMediator(cfg => cfg.UseBlazor());
Middleware
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) { try { 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 cfg.AddOpenEventMiddleware(typeof(ExceptionHandlerEventMiddleware<>));});