# `event_bus`

| Package | Kind | Provides the role | Needs | Choose with |
| --- | --- | --- | --- | --- |
| [`smf_event_bus`](https://pub.dev/packages/smf_event_bus) | infrastructure | Events | nothing | `-m event_bus` |

`event_bus` lets parts of the app that do not know each other, such as two features, exchange events through one service. The service is built on the [event_bus](https://pub.dev/packages/event_bus) package.

## What it adds to the app

The module adds `event_bus: ^2.0.1` to the dependencies, and `lib/core/events/event_bus_communication_service.dart` with the implementation of the service on an `EventBus`.

Whichever module provides it, the events role adds `lib/core/events/communication_service.dart` with:

- `AppEvent`, the base class of the events, such as `final class ItemAdded extends AppEvent`;
- the `CommunicationService` interface, where `fire(event)` sends an event and `on<T>()` is the stream of the events of type `T`;
- `createCommunicationService()`, which returns the service of the app.

In the [guide for coding agents](https://doc.saymyframe.com/guides/coding-agents.md) of the app, the events role describes the service under "Events", and the module adds when a listener gets an event.

## How events are delivered

- An event goes to everyone listening to its type, or to a type it extends or implements, so `on<AppEvent>()` gets every event.
- Listeners get an event after the code that fires it has completed, not during `fire`.
- A listener gets the events fired after it starts listening.

Whichever module provides the events role, a listener of a type gets each event of that type once, in the order the events were fired, and a listener of an unrelated type gets none. SMF's CI checks this in every app with the role in [the matrix of the built-in modules](https://doc.saymyframe.com/contributing.md#generated-apps).

## Getting the service

The service is created on first use, without waiting, so the app starts as fast as it would without it. With a module of dependency injection, the events role registers the service in the container as a lazy singleton, and a feature takes it with `resolve` in its composition file. Without a container, the code of the app gets it from `createCommunicationService()`, which always returns the same service. Don't create a second one with `createEventBusCommunicationService()`, because the listeners of one service do not get the events fired into another. See [Services and state](https://doc.saymyframe.com/guides/services.md#events).

## Choosing it

`smf create` asks which module provides the events of the app, and offers None as well. To choose it without the question:

```bash
smf create my_app -m event_bus
```
