Nucleus .Net Core CMS

Event Handlers

Nucleus Extensions implement an Event Handler to execute code when a system or extension event is raised, and can raise events of their own to be handled within the extension, or by another extension. The data provider for most Nucleus core entities raises events when data is changed (when a record is created, modified or deleted), and the Nucleus entity framework migration class raises events when a database schema migration is completed.

Raising an Event

To raise an event, add a reference to the Nucleus IEventDispatcher to your constructor. Call RaiseEvent to raise an event.

Handling an Event

To handle an event, create a class which implements the ISystemEventHandler or ISingletonSystemEventHandler interface.

The ISingletonSystemEventHandler interface was added in Nucleus 1.3. Previously, singleton event handlers could implement ISystemEventHandler, but this causes problems when retrieving event handler implementations from dependency injection when there are both scoped and singleton handlers for the same model and event.

The functions used to raise and handle events both specify a TModel and TEvent. The TModel type is the type of the model entity which has changed, and the TEvent type represents the event which occurred. TEvent can be any type, but Nucleus has classes for create,
update, and delete. If you need to represent a different kind of event, just create a class for it. The TEvent class is used as a key in the dependency injection services collection, and does not need to inherit any class, or have any methods or properties.

Example

The example below is from the core Documents module. This class adds a transient System Event Handler to receive Nucleus system events - in this case, a MigrateEvent which is triggered after a data provider migration script is executed. Some extensions use the MigrateEvent to perform post-installation or post-upgrade steps which can't be included in a database migration script.

using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Nucleus.Modules.Documents.DataProviders;
using Nucleus.Abstractions.Search;
using Nucleus.Data.EntityFramework;
using Nucleus.Data.Common;
using Nucleus.Abstractions.EventHandlers;

[assembly:HostingStartup(typeof(Nucleus.Modules.Documents.Startup))]

namespace Nucleus.Modules.Documents;

public class Startup : IHostingStartup
{
  public void Configure(IWebHostBuilder builder)
  {
    builder.ConfigureServices((context, services) => 
    {
      // code which does not demonstrate event handling has been removed from this example

      services.AddSingletonSystemEventHandler<MigrateEventArgs, MigrateEvent, MigrationEventHandler>();
    });
  }
}

public class MigrationEventHandler : Nucleus.Abstractions.EventHandlers.ISystemEventHandler<MigrateEventArgs, MigrateEvent>
{
  public Task Invoke(MigrateEventArgs item)
  {
    if (item.SchemaName == "Nucleus.Modules.Documents")
    {
      if (item.ToVersion == new System.Version(1,0,0))
      {
        // This is an example of how you would execute code after a db schema migration.
        // There is no implementation in this example - you would add your code to implement event handling here. 
      }
    }
    return Task.CompletedTask;
  }
}

Note:: The Data migration event MigrateEvent is sent to all subscribers, so you must check the .SchemaName property of the MigrateEventArgs object that is passed to the Invoke method to make sure that it applies to your extension. Data schema migration doesn't happen immediately when you install an update, it runs the first time the extension accesses the database.