Events in Drupal 8 are a powerful mechanism of interaction between modules. Some component dispatch events (EventDispatcher) and some component register and perform some action (EventSubscriber) when an event occurs. Drupal’s core system and module dispatch many events that play an important role in connecting code from one module to another.

Here is how to define an Event.

Create Event dir under src like src/Event, Create event classes under that directory like below. We first declare a final class so that it cannot be extended and provide a unique name to our event. This is a best practice to attach a unique name to events using a constant.

<?php
namespace Drupal\emeevents\Event;
/**
 * Class EmeEvents
 * @package Drupal\emeevents\Event
 */
final class EmeEvents {
/**
   * Name of the event fired when a new EmeEvents is reported.
   * @Event
   * @see \Drupal\emeevents\Event\EmeEvents
   * @var string
   */
  const NEW_STATICS = 'emeevents.email_statics';
}

Here is our event class, don’t forget to extend Events from Symfony\Component\EventDispatcher\Event

<?php

namespace Drupal\emeevents\Event;

use Symfony\Component\EventDispatcher\Event;

/**
 * Class EmailStaticsEvent
 * @package Drupal\emeevents\Event
 */
class EmailStaticsEvent extends Event {

  /**
   * Email.
   *
   * @var string
   */
  protected $email;

  /**
   * Subject
   *
   * @var string
   */
  protected $subject;

  /**
   * Body
   *
   * @var string
   */
  protected $body;

  /**
   * EmailStaticsEvent constructor.
   * @param $email
   * @param $subject
   * @param $body
   */
  public function __construct($email, $subject, $body) {
    $this->email = $email;
    $this->subject = $subject;
    $this->body = $body;
  }

  /**
   * Return email
   * @return string
   */
  public function getEmail(){
    return $this->email;
  }

  /**
   * Return subject
   * @return string
   */
  public function getSubject(){
    return $this->subject;
  }

  /**
   * Return body
   * @return string
   */
  public function getBody(){
    return $this->body;
  }

}

Now we will dispatch the event using a custom form, create below form class under src/Form/

<?php

namespace Drupal\emeevents\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Drupal\emeevents\Event\EmeEvents;
use Drupal\emeevents\Event\EmailStaticsEvent;

/**
 * Class EmeEventsForm
 * @package Drupal\emeevents\Form
 */
class EmeEventsForm extends FormBase {

  /**
   * The event dispatcher service.
   *
   * @var \Symfony\Component\EventDispatcher\EventDispatcherInterface
   */
  protected $eventDispatcher;

  /**
   * EmeEventsForm constructor.
   * @param EventDispatcherInterface $event_dispatcher
   */
  public function __construct(EventDispatcherInterface $event_dispatcher) {
    $this->eventDispatcher = $event_dispatcher;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('event_dispatcher')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $form['intro'] = [
      '#markup' => '<p>' . $this->t('This form will dispach event when submit') . '</p>',
    ];

    $form['email'] = array(
        '#type' => 'email',
        '#required' => true,
        '#title' => $this->t('Email'),
    );

    $form['subject'] = [
        '#type' => 'textfield',
        '#required' => true,
        '#title' => $this->t('Email Subject'),
    ];

    $form['body'] = [
      '#type' => 'textarea',
      '#required' => FALSE,
      '#title' => t('Statics Body'),
      '#cols' => 60,
      '#rows' => 5,
    ];

    $form['actions'] = [
      '#type' => 'actions',
    ];

    $form['actions']['submit'] = [
      '#type' => 'submit',
      '#value' => $this->t('Submit'),
    ];

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'eme_events_form';
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $email = $form_state->getValue('email');
    $subject = $form_state->getValue('subject');
    $body = $form_state->getValue('body');

    $event = new EmailStaticsEvent($email, $subject, $body);

    $this->eventDispatcher->dispatch(EmeEvents::NEW_STATICS, $event);
  }

}

Register your event subscriber as below.

<?php
namespace Drupal\emeevents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\emeevents\Event\EmeEvents;
use Drupal\emeevents\Event\EmailStaticsEvent;
/**
 * Class EmailStaticsEventSubscriber
 * @package Drupal\emeevents\EmailStaticsEventSubscriber
 */
class EmailStaticsEventSubscriber implements EventSubscriberInterface
{
use StringTranslationTrait;
/**
     * {@inheritdoc}
     */
    public static function getSubscribedEvents()
    {
        $events[EmeEvents::NEW_STATICS][] = ['sendEmail'];
        return $events;
    }
public function sendEmail(EmailStaticsEvent $event)
    {
$mailManager = \Drupal::service('plugin.manager.mail');
        $module = 'emeevents';
        $key = 'emeevent_email_statics'; // this will be your template id
        $to = \Drupal::currentUser()->getEmail();
        $params['message'] = $event->getReport();
        $params['subject'] = $event->getReport();
        $langcode = \Drupal::currentUser()->getPreferredLangcode();
        $send = true;
        
        $result = $mailManager->mail($module, $key, $to, $langcode, $params, NULL, $send);
        if ($result['result'] !== true) {
            //success message
        } else {
            //failed message
        }
    }
}

emeevents.services.yml

services:
  emeevents.event_subscriber:
    class: Drupal\emeevents\EmailStaticsEventSubscriber
    tags:
      - {name: event_subscriber}