Custom Alerts

Custom Alerts

Last time I wrote about changes I recently made to my alert library.

This time I’ll demonstrate how to override a “standard” alert type. Let’s start by defining a custom alert class:

public class CustomErrorAlert : ErrorAlert
{
    public CustomErrorAlert(
        ILogger<CustomErrorAlert> logger
        ) : base(logger)
    {

    }

    protected override void OnInvoke(
        params object[] args
        )
    {
        // This demonstrates how to override 'standard alert' handlers
        //   with custom logic.
        _logger.LogError($"The '{GetType().Name}' error alert handler was called.");

        // Optionally, give the base class a chance.
        //base.OnInvoke(args);
    }
}

So, we have a class called CustomErrorAlert, that derives from the ErrorAlert type. That hierarchy is important. We’ll need our custom error alert to derive from ErrorAlert or the entire thing falls apart.

The class overrides the OnInvoke method. That’s the method that the alert service calls, on our behalf, whenever an alert is raised. In this case, whenever an error alert is raised. My example is pretty thin, granted, but I’m really just trying to demonstrate how to override an alert, not how to write a good error handler. I’ll leave that last part up to you. :o)

Now that we have our custom error alert type, how do we tell the alert service to use it? We do that in the Startup class, like this:

public void ConfigureServices(IServiceCollection services)
{
    services.AddAlertServices(options =>
    {
        options.SetErrorAlertType<CustomErrorAlert>();
    });
}

This sets our custom alert type as an override to the “normal” error alert type. That way, when the alert service is created, on startup, it will register our type, instead of the ErrorAlert type, and will send all error alerts to our CustomErrorAlert class, instead.

How do we send an error alert? Like this:

@page "/"
@inject IAlertService Alerts

<div class="form-group">
    <button @onclick="@(() => Alerts.Raise<ErrorAlert>())">Raise Error Alert</button>
</div>

Notice that we didn’t have to specify our CustomErrorAlert type? The alert service takes care of substituting our custom type for the ErrorAlert type. That way, if the error alert type is overridden again, or in some different way, we won’t have to change our code to send the appropriate alert type.


What about purely custom alert types? Let’s go look at that next.

Let’s start by defining our custom alert class:

public class CustomAlert : AlertEventBase
{
    public static Action<string> OnAlert { get; set; }

    protected override void OnInvoke(
        params object[] args
        )
    {
        // This demonstrates one way to integrate alerts with the UI.
        OnAlert?.Invoke($"Alert raised at: '{DateTime.Now}'");

        // Optionally, give the base class a chance.
        base.OnInvoke(args);
    }
}

For this example, I did something different and created a simple delegate that our handler will call, whenever the alert is raised. I’ll show how to use that here, shortly.

Let’s go look at how to register our CustomAlert type, with the alert service:

public void ConfigureServices(IServiceCollection services)
{
    services.AddAlertServices(options =>
    {
        options.AddCustomAlertType<CustomAlert>();
    });
}

This is how to use the custom alert, at runtime:

@page "/"
@inject IAlertService Alerts

<div class="form-group pt-3">
	<button @onclick="@(() => Alerts.Raise<CustomAlert>())">Raise Custom Alert</button>
	@if (!string.IsNullOrEmpty(AlertMsg))
	{
		<p style="color: blue" class="pl-5 pt-1">@AlertMsg</p>
	}
</div>

@code {
	string AlertMsg { get; set; }
	protected override void OnInitialized()
	{
		CustomAlert.OnAlert += (m) => AlertMsg = m;
		base.OnInitialized();
	}
}

As we can see, the custom alert is raised pretty much like any other alert. Notice how we set the delegate in the OnInitialized method. That way, we set the AlertMsg property whenever the alert is raised. Now, obviously, this is a contrived example. We could, just as easily, have set the text of the AlertMsg property ourselves, without routing an alert to do it. But, what I’m trying for, is a simple example to demonstrate the idea of a custom alert. Where you take that idea is your business.

I hope everyone enjoys the alert library. I hope you find many happy uses for it, in your next project.


The source code for this library is available, for free, HERE.

The NUGET package is available, for free, HERE.

There is a working quick start sample, for the alert project, HERE.


Photo by Peter Okwara on Unsplash