El lanzamiento del evento NopCommerce y el mecanismo de suscripción se explican en detalle

En el marco de Nop, puede ver que el mecanismo de eventos se utiliza en muchos lugares, especialmente la actualización de la memoria caché. Algunas personas pueden preguntarse, ¿qué problema resuelve esto?
Si tenemos ese escenario, después de que un cliente se registre, actualizaremos el caché y luego enviaremos un correo electrónico de registro, la práctica habitual es:

void InsertCustomer()
{
    1. 新增到数据库
    2. 插入到缓存
    3. 发送注册邮件
}

No hay ningún problema al hacer esto, pero dichos códigos estarán estrechamente unidos. Si desea agregar otra acción para enviar cupones después del registro, también puede agregar una acción para enviar cupones dentro, de modo que el negocio esté seguro. La unión está firmemente en el nuevo método, ¿cómo lo hace Nop?

void Insert()
{
    1. 新增到数据库
    2. 发布一条新增消息
}

class CacheConsumer: IConsumer<EntityInsertedEvent<Customer>>
{
    public void HandleEvent(EntityUpdatedEvent<Setting> eventMessage)
    {
        //新增缓存
    }
}

class MailConsumer: IConsumer<EntityInsertedEvent<Customer>>
{
    public void HandleEvent(EntityUpdatedEvent<Setting> eventMessage)
    {
        //发送邮件
    }
}

Explica específicamente el proceso de ejecución:

  1. Después de agregar un dato, publique un mensaje en el administrador de mensajes
  2. Todos los consumidores que se suscriban al nuevo mensaje recibirán el mensaje.
  3. Los consumidores ejecutan eventos específicos, como agregar caché, enviar correos electrónicos, etc.

La implementación técnica de Nop puede ser un poco más complicada. No utiliza RabbitMQ tradicional y otras colas de mensajes de terceros, pero combina la inyección de dependencia de Autofac para lograr este diseño ingeniosamente:

  1. Interfaz de publicación de eventos IEventPublisher
  2. EventPublisher implementa la clase IEventPublisher, las funciones principales incluyen publicar eventos y notificar a los suscriptores
  3. Consumidor Interfaz de consumidor (suscriptor de eventos)
  4. Interfaz de suscriptor ISubscriptionService, resuelva todos los suscriptores
  5. Implementación específica de SubscriptionService

A continuación, echemos un vistazo a la clase de implementación específica, tomando CategoryService como ejemplo, para eliminar detalles innecesarios:

public virtual void InsertCategory(Category category)
{
    _categoryRepository.Insert(category);
    //发布一条消息
    _eventPublisher.EntityInserted(category);
}

La clase de PriceCacheEventConsumer que se suscribe a este mensaje tiene el siguiente código:

public partial class PriceCacheEventConsumer : IConsumer<EntityInsertedEvent<Category>>
{
    public void HandleEvent(EntityInsertedEvent<Category> eventMessage)
    {
        _cacheManager.RemoveByPattern(NopCatalogDefaults.ProductCategoryIdsPatternCacheKey);
    }
}

El código anterior ha eliminado el factor de interferencia, vemos que esta clase hereda de IConsumer

A continuación, echemos un vistazo a lo que hace EventPublisher:

/// <summary>
/// 发布到消费者
/// </summary>
protected virtual void PublishToConsumer<T>(IConsumer<T> x, T eventMessage)
{
    try
    {
        x.HandleEvent(eventMessage); //执行消费者订阅方法
    }
    catch (Exception exc)
    {
    }
}

/// <summary>
/// 发布事件,注意,是整个实现的核心
/// </summary>
public virtual void Publish<T>(T eventMessage)
{
    //利用控制反转IOC技术,查找所有消费者类
    var subscribers = _subscriptionService.GetSubscriptions<T>()
        .Where(subscriber => PluginManager.FindPlugin(subscriber.GetType())?.Installed ?? true).ToList();

    //调用PublishToConsumer,执行对应消费者类的方法,这个是关键
    subscribers.ForEach(subscriber => PublishToConsumer(subscriber, eventMessage));
}

Servicio de publicación de eventos: SubscriptionService, esta clase es una clase de herramienta, proporciona un método para encontrar consumidores según el tipo GetSubscriptions

public IList<IConsumer<T>> GetSubscriptions<T>()
{
    return EngineContext.Current.ResolveAll<IConsumer<T>>().ToList();
}

EngineContext en la clase anterior, Nop engine manager, Current se refiere al motor actual, ResolveAll toma la clase de consumidor del contenedor, consulte Autofac para obtener tecnología específica

Para resumir:

  1. Todo el código se da cuenta del desacoplamiento y ya no depende el uno del otro.
  2. Publicar suscripción de mensaje, no utiliza directamente la cola de mensajes de terceros RabbitMQ, por lo que no hay un terminal de monitoreo separado
  3. Usando la tecnología de control de inversión, resuelve inteligentemente la dificultad de encontrar consumidores, si usa la reflexión, el rendimiento disminuirá

Supongo que te gusta

Origin www.cnblogs.com/honzhez/p/12699121.html
Recomendado
Clasificación