Skip to content

PubSubExtensions

La clase PubSubExtensions proporciona métodos de extensión relacionados con la funcionalidad de PubSub. Estos métodos permiten determinar si un tipo implementa una interfaz genérica, obtener eventos y manejadores de eventos, y extraer tipos de eventos de interfaces de manejadores de eventos.

namespace CodeDesignPlus.Net.PubSub.Extensions;
/// <summary>
/// Provides extension methods related to the PubSub functionality.
/// </summary>
public static class PubSubExtensions
{
/// <summary>
/// Determines whether an instance of a specified type can be assigned to a variable of the current type.
/// </summary>
/// <param name="type">The current type.</param>
/// <param name="interface">The type to compare with the current type.</param>
/// <returns>Returns true if <paramref name="type"/> implements <paramref name="interface"/>.</returns>
public static bool IsAssignableGenericFrom(this Type type, Type @interface)
{
return Array.Exists(type.GetInterfaces(), x => x.IsGenericType && x.GetGenericTypeDefinition() == @interface);
}
/// <summary>
/// Retrieves all non-abstract classes that derive from <see cref="IDomainEvent"/>.
/// </summary>
/// <returns>A list of event types.</returns>
public static List<Type> GetEvents()
{
return AppDomain.CurrentDomain
.GetAssemblies()
.SelectMany(assembly => assembly.GetTypes())
.Where(t => typeof(IDomainEvent).IsAssignableFrom(t) && t.IsClass && !t.IsAbstract && !t.IsInterface)
.ToList();
}
/// <summary>
/// Scans and returns classes that implement the <see cref="IEventHandler{TEvent}"/> interface.
/// </summary>
/// <returns>A list of event handler types.</returns>
public static List<Type> GetEventHandlers()
{
return AppDomain.CurrentDomain
.GetAssemblies()
.Where(assembly => assembly.GetName().Name != "DynamicProxyGenAssembly2")
.SelectMany(x => x.GetTypes())
.Where(x =>
x.IsClass &&
x.IsAssignableGenericFrom(typeof(IEventHandler<>))
).ToList();
}
/// <summary>
/// Retrieves the first interface of a given type that is a generic type instance of the <see cref="IEventHandler{TEvent}"/> interface.
/// </summary>
/// <param name="eventHandler">The type from which to retrieve the interface.</param>
/// <returns>
/// The first matching interface of type <see cref="IEventHandler{TEvent}"/>, or null if no such interface is found.
/// </returns>
public static Type GetInterfaceEventHandlerGeneric(this Type eventHandler)
{
return Array.Find(eventHandler.GetInterfaces(), x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IEventHandler<>));
}
/// <summary>
/// Given an interface of type <see cref="IEventHandler{TEvent}"/>, retrieves the event type it handles.
/// </summary>
/// <param name="interfaceEventHandlerGeneric">The <see cref="IEventHandler{TEvent}"/> type interface from which to retrieve the event type.</param>
/// <returns>
/// The event type handled by the interface, or null if not found.
/// </returns>
/// <remarks>
/// This method assumes that the provided type is an instance of the generic interface <see cref="IEventHandler{TEvent}"/>.
/// If this is not the case, the method may return unexpected results.
/// </remarks>
public static Type GetEventType(this Type interfaceEventHandlerGeneric)
{
return Array.Find(interfaceEventHandlerGeneric.GetGenericArguments(), x => x.IsClass && !x.IsAbstract && typeof(IDomainEvent).IsAssignableFrom(x));
}
}

  • Determinación de asignabilidad genérica: Verifica si un tipo implementa una interfaz genérica específica.
  • Obtención de eventos: Recupera todos los tipos de eventos que derivan de IDomainEvent.
  • Obtención de manejadores de eventos: Escanea y devuelve clases que implementan la interfaz IEventHandler<TEvent>.
  • Extracción de tipos de eventos: Extrae el tipo de evento manejado por una interfaz de manejador de eventos genérica.

La clase PubSubExtensions proporciona los siguientes métodos de extensión:

Type: public static bool IsAssignableGenericFrom(this Type type, Type @interface)

Determina si una instancia de un tipo especificado puede asignarse a una variable del tipo actual.

var eventHandlerType = typeof(UserRegisteredEventHandler);
var isAssignable = eventHandlerType.IsAssignableGenericFrom(typeof(IEventHandler<>));
Console.WriteLine(isAssignable); // True si UserRegisteredEventHandler implementa IEventHandler<TEvent>

Type: public static List<Type> GetEvents()

Recupera todas las clases no abstractas que derivan de IDomainEvent.

var events = PubSubExtensions.GetEvents();
foreach (var eventType in events)
{
Console.WriteLine(eventType.Name);
}

Type: public static List<Type> GetEventHandlers()

Escanea y devuelve clases que implementan la interfaz IEventHandler<TEvent>.

var eventHandlers = PubSubExtensions.GetEventHandlers();
foreach (var handlerType in eventHandlers)
{
Console.WriteLine(handlerType.Name);
}

Type: public static Type GetInterfaceEventHandlerGeneric(this Type eventHandler)

Recupera la primera interfaz de un tipo dado que es una instancia de tipo genérico de la interfaz IEventHandler<TEvent>.

var handlerType = typeof(UserRegisteredEventHandler);
var interfaceType = handlerType.GetInterfaceEventHandlerGeneric();
Console.WriteLine(interfaceType?.Name);

Type: public static Type GetEventType(this Type interfaceEventHandlerGeneric)

Dada una interfaz de tipo IEventHandler<TEvent>, recupera el tipo de evento que maneja.

var interfaceType = typeof(IEventHandler<UserRegisteredEvent>);
var eventType = interfaceType.GetEventType();
Console.WriteLine(eventType?.Name);

La clase PubSubExtensions proporciona métodos de extensión útiles para trabajar con la funcionalidad de PubSub en aplicaciones .NET. Estos métodos facilitan la determinación de asignabilidad genérica, la obtención de eventos y manejadores de eventos, y la extracción de tipos de eventos de interfaces de manejadores de eventos, mejorando así la capacidad de gestión y suscripción de eventos en el sistema.