Skip to content

IEventHandler

La interfaz IEventHandler define el contrato para los manejadores de eventos en el sistema PubSub. Los manejadores de eventos son responsables de procesar eventos específicos cuando se publican en el sistema.

namespace CodeDesignPlus.Net.PubSub.Abstractions;
/// <summary>
/// Base interface for implementing an event handler for a defined event.
/// </summary>
/// <typeparam name="TEvent">Integration Event</typeparam>
public interface IEventHandler<in TEvent>
where TEvent : IDomainEvent
{
/// <summary>
/// Invoked by the event bus when an event to which it is subscribed is detected.
/// </summary>
/// <param name="data">Event information</param>
/// <param name="token">Cancellation Token</param>
/// <returns>A Task representing the asynchronous operation</returns>
Task HandleAsync(TEvent data, CancellationToken token);
}

Métodos


La interfaz IEventHandler define un solo método que se encarga de procesar un evento específico cuando se publica en el sistema.

HandleAsync

Type: Task HandleAsync(TEvent data, CancellationToken token)

Este método se encarga de procesar un evento específico cuando se publica en el sistema. El método recibe el evento a procesar y un token de cancelación para monitorear las solicitudes de cancelación.

Implementación de un manejador de eventos

Para implementar un manejador de eventos, se debe crear una clase que implemente la interfaz IEventHandler. A continuación se muestra

using System;
using CodeDesignPlus.Net.PubSub.Abstractions;
using Microsoft.Extensions.Logging;
namespace CodeDesignPlus.Net.PubSub.Sample.Handlers;
public class UserCreatedEventHandler(ILogger<UserCreatedEventHandler> logger) : IEventHandler<UserCreatedEvent>
{
public Task HandleAsync(UserCreatedEvent data, CancellationToken token)
{
logger.LogInformation("Handling event {@data}", data);
return Task.CompletedTask;
}
}

Registrar un manejador de eventos

Para registrar un manejador de eventos en el sistema de inyección de dependencias de .NET, se debe utilizar el método de extensión AddPubSub que invoca AddEventHandler proporcionado por la clase ServiceCollectionExtensions.

namespace CodeDesignPlus.Net.PubSub.Extensions;
/// <summary>
/// Provides extension methods for adding PubSub services to the IServiceCollection.
/// </summary>
public static class ServiceCollectionExtensions
{
/// <summary>
/// Adds PubSub services to the specified IServiceCollection using the provided configuration.
/// </summary>
/// <param name="services">The IServiceCollection to add the services to.</param>
/// <param name="configuration">The configuration to use for PubSub options.</param>
/// <returns>The IServiceCollection with PubSub services added.</returns>
/// <exception cref="ArgumentNullException">Thrown if services or configuration is null.</exception>
/// <exception cref="PubSubException">Thrown if the PubSubOptions section is not found in the configuration.</exception>
public static IServiceCollection AddPubSub(this IServiceCollection services, IConfiguration configuration)
{
ArgumentNullException.ThrowIfNull(services);
ArgumentNullException.ThrowIfNull(configuration);
var section = configuration.GetSection(PubSubOptions.Section);
if (!section.Exists())
throw new PubSubException($"The section {PubSubOptions.Section} is required.");
services
.AddOptions<PubSubOptions>()
.Bind(section)
.ValidateDataAnnotations();
var options = section.Get<PubSubOptions>();
services
.AddCore(configuration)
.AddEventsHandlers()
.TryAddSingleton<IPubSub, PubSubService>();
if (options.UseQueue)
{
services.TryAddSingleton<IEventQueue, EventQueueService>();
services.TryAddEnumerable(ServiceDescriptor.Singleton<IHostedService, EventQueueBackgroundService>());
}
if (options.EnableDiagnostic)
services.TryAddSingleton<IActivityService, ActivitySourceService>();
return services;
}
/// <summary>
/// Adds PubSub services to the specified IServiceCollection using the provided configuration and setup options.
/// </summary>
/// <param name="services">The IServiceCollection to add the services to.</param>
/// <param name="configuration">The configuration to use for PubSub options.</param>
/// <param name="setupOptions">An action to configure the PubSub options.</param>
/// <returns>The IServiceCollection with PubSub services added.</returns>
/// <exception cref="ArgumentNullException">Thrown if services, configuration, or setupOptions is null.</exception>
public static IServiceCollection AddPubSub(this IServiceCollection services, IConfiguration configuration, Action<PubSubOptions> setupOptions)
{
ArgumentNullException.ThrowIfNull(services);
ArgumentNullException.ThrowIfNull(configuration);
ArgumentNullException.ThrowIfNull(setupOptions);
var pubSubOptions = new PubSubOptions();
setupOptions(pubSubOptions);
services
.AddOptions<PubSubOptions>()
.Configure(setupOptions)
.ValidateDataAnnotations();
services
.AddCore(configuration)
.AddEventsHandlers()
.TryAddSingleton<IPubSub, PubSubService>();
if (pubSubOptions.UseQueue)
{
services.TryAddSingleton<IEventQueue, EventQueueService>();
services.TryAddEnumerable(ServiceDescriptor.Singleton<IHostedService, EventQueueBackgroundService>());
}
if (pubSubOptions.EnableDiagnostic)
services.TryAddSingleton<IActivityService, ActivitySourceService>();
return services;
}
/// <summary>
/// Adds event handlers to the specified IServiceCollection.
/// </summary>
/// <param name="services">The IServiceCollection to add the event handlers to.</param>
/// <returns>The IServiceCollection with event handlers added.</returns>
private static IServiceCollection AddEventsHandlers(this IServiceCollection services)
{
var eventsHandlers = PubSubExtensions.GetEventHandlers();
foreach (var eventHandler in eventsHandlers)
{
var interfaceEventHandlerGeneric = eventHandler.GetInterfaceEventHandlerGeneric();
var eventType = interfaceEventHandlerGeneric.GetEventType();
if (eventType == null)
continue;
var eventHandlerBackgroundType = typeof(RegisterEventHandlerBackgroundService<,>).MakeGenericType(eventHandler, eventType);
services.TryAddEnumerable(ServiceDescriptor.Singleton(typeof(IHostedService), eventHandlerBackgroundType));
services.TryAddScoped(eventHandler);
}
return services;
}
}

Conclusiones


La interfaz IEventHandler es fundamental para el manejo de eventos en el sistema PubSub. Permite a los desarrolladores definir la lógica específica para procesar eventos cuando se publican. Al implementar esta interfaz y registrar los manejadores de eventos en el contenedor de dependencias, se puede construir un sistema de eventos robusto y escalable.