How to put form in a block programmaticaly

Putting some form in a block is matter of creating a new block and assigning a form to it through form_builder that is called through dependency injection(DI) and then using method getForm that will get rendered array of this form, which is exactly what build method for block expects to output

so we create new block plugin in our module  my_module/src/Plugins/Block/ExampleFormBlock.php, add necessary DI stuff and in the end inject the form we want to put into the block with its full path to the class.

<?php

namespace Drupal\form_api_example\Plugin\Block;

use Drupal\Core\Block\BlockBase;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Form\FormBuilderInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 *
 * @Block(
 *   id = "example_form_block",
 *   admin_label = @Translation("Form in a block")
 * )
 */
class ExampleFormBlock extends BlockBase implements ContainerFactoryPluginInterface {

  /**
   * Form builder service.
   *
   * @var \Drupal\Core\Form\FormBuilderInterface
   */
  protected $form_builder;

  /**
   * {@inheritdoc}
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition, FormBuilderInterface $form_builder) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
    $this->form_builder = $form_builder;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get('form_builder')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function build() {
    $output = [
      'description' => [
        '#markup' => $this->t('Using form provided by Drupal\form_api_example\Form\SimpleForm'),
      ],
    ];

    $output['form'] = $this->form_builder->getForm('Drupal\form_api_example\Form\SimpleForm');
    return $output;
  }

}