EventBus In eShop, eventbusineshop

Source: Internet
Author: User
Tags eventbus

EventBus In eShop, eventbusineshop
Introduction

Everyone seems tired of analyzing source code. I am also tired of it, but I cannot analyze the things behind it without looking at it. From ease to difficulty is a necessary process.

Let's talk about EventBus today. A few days ago, the great gods in the park have already split it. Today, I will analyze the implementation of EventBus IN THE eShop project through the shoulders of the great gods.

Recently found that forwarding articles do not write the source, hereby add the link: http://inday.cnblogs.com

Parse source code

We know that EventBus is used to remove the dependency between Publisher and Subscriber, so that our Publisher does not need to know how many Subscribers are there. We only need to register and manage them through EventBus. In the eShop project, there is such an interface IEventBus (eShopOnContainers \ src \ BuildingBlocks \ EventBus \ Abstractions)

public interface IEventBus{    void Subscribe<T, TH>(Func<TH> handler)        where T : IntegrationEvent        where TH : IIntegrationEventHandler<T>;    void Unsubscribe<T, TH>()        where TH : IIntegrationEventHandler<T>        where T : IntegrationEvent;    void Publish(IntegrationEvent @event);}

We can see that this interface defines some operations required by EventBus. Compared with EventBus, the relevant functions are consistent. Let's take a look at its implementation class: EventBusRabbitMQ. We can see from the name that, this is an EventBus managed through RabbitMQ. We can see that it uses IEventBusSubscriptionsManager for subscription and storage, that is, in the following article:

private readonly ConcurrentDictionary<Type, List<Type>> _eventAndHandlerMapping;

In the Demo, Microsoft extracts the interface and extracts some common methods. However, the core is Dictionary <string, List <Delegate>, which is used for Map ing. Subscribe and UnSubscribe are used to Subscribe and cancel, and Publish is used for publishing.

public void Subscribe<T, TH>(Func<TH> handler)    where T : IntegrationEvent    where TH : IIntegrationEventHandler<T>{    var eventName = typeof(T).Name;    var containsKey = _subsManager.HasSubscriptionsForEvent<T>();    if (!containsKey)    {        if (!_persistentConnection.IsConnected)        {            _persistentConnection.TryConnect();        }        using (var channel = _persistentConnection.CreateModel())        {            channel.QueueBind(queue: _queueName,                                exchange: BROKER_NAME,                                routingKey: eventName);        }    }    _subsManager.AddSubscription<T, TH>(handler);}

We can see that at the time of subscription, EventBus will check whether there is a corresponding registration in Map. If not, first go back to RabbitMQ and create a new channel for binding, then register the ing in Map.

UnSubscribe cancels the ing directly from the Map. The OnEventRemoved event is used to determine whether the subscriber of the ing in the Map is null. If it is null, the channel is closed from RabbitMQ.

In the RabbitMQ constructor, we can see this creation: CreateConsumerChannel (), where an EventingBasicConsumer is created, when there is a new message in the Queue, the handler (subscribers) registered in Map will be executed through ProcessEvent. The figure may be clearer:


In the ProcessEvent method, go back to Map to find subscribers, and then execute through dynamic reflection:

private async Task ProcessEvent(string eventName, string message){    if (_subsManager.HasSubscriptionsForEvent(eventName))    {         var eventType = _subsManager.GetEventTypeByName(eventName);        var integrationEvent = JsonConvert.DeserializeObject(message, eventType);        var handlers = _subsManager.GetHandlersForEvent(eventName);        foreach (var handlerfactory in handlers)        {            var handler = handlerfactory.DynamicInvoke();            var concreteType = typeof(IIntegrationEventHandler<>).MakeGenericType(eventType);            await (Task)concreteType.GetMethod("Handle").Invoke(handler, new object[] { integrationEvent });        }    }}

Microsoft decouples the dependency between Publisher and Subscribers through simple code. We reference the following summary:

Application

In catalog. in the api, Microsoft encountered EventBus, which I mentioned in the previous article. This is one of my doubts, because the catalog does not subscribe to the operation and the Publish operation is directly executed, I thought it was an empty operation. Later I checked the Basket. I only know why Microsoft uses RabbitMQ.

With RabbitMQ, we can not only decouple classes, but also decouple across projects, languages, and platforms. publisher only needs to transmit the message body (IntegrationEvent) to RabbitMQ, the Consumer obtains the message body from the Queue and pushes the message body to Subscribers for corresponding operations. Let's take a look at Basket. Api. Startup. cs:

protected virtual void ConfigureEventBus(IApplicationBuilder app){    var catalogPriceHandler = app.ApplicationServices        .GetService<IIntegrationEventHandler<ProductPriceChangedIntegrationEvent>>();    var orderStartedHandler = app.ApplicationServices        .GetService<IIntegrationEventHandler<OrderStartedIntegrationEvent>>();    var eventBus = app.ApplicationServices.GetRequiredService<IEventBus>();    eventBus.Subscribe<ProductPriceChangedIntegrationEvent, ProductPriceChangedIntegrationEventHandler>        (() => app.ApplicationServices.GetRequiredService<ProductPriceChangedIntegrationEventHandler>());    eventBus.Subscribe<OrderStartedIntegrationEvent, OrderStartedIntegrationEventHandler>        (() => app.ApplicationServices.GetRequiredService<OrderStartedIntegrationEventHandler>());}

In this method, we can see the Subscribe operation. It's a little funny to think about the previous questions, but the research is also good, right!

Summary

Today, we have read the application of EventBus in the Demo and summarized it.

1. EventBus can decouple the dependencies between the subscriber and the publisher.

2. RabbitMQ can be used to decouple subscribers and publishers across projects, platforms, and languages.

In the Demo, we can see that the Subscribe is managed through the Dictionary Memory, so our Subscribe is only in the Basket. but Microsoft defined it through the IEventBusSubscriptionsManager interface. We can customize it based on our own needs and make it distributed, such as using memcached.

Conclusion

Every month to the next ten days will be busy, so the article press conference is slow, but I will continue to learn eShop. In order to learn, I have created a group for everyone to come and learn together, you can come in with any suggestions or questions.

Although eShop is good, we do not recommend that you put it in the production environment. After all, it is a Demo and the ALPHA version is used to learn a good teaching material. This is a hodgedge, you will learn a lot of new things during your study. If you are optimistic about the development of core, you can study it together.

QQ: 376248054

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.