Cache a block by a custom entity rendered within
By any reason I do not really get the block rendering to respect my cache keys set wherever. It only respects set cache contexts so I create a custom cache context:

In pw_basic.services.yml (pw_basic is the name ofthe module)

  cache_context.politician:
    class: Drupal\pw_basic\Cache\PoliticianCacheContext
    arguments: ['@current_route_match']
    tags:
      - { name: cache.context }


The politician cache context class:

class PoliticianCacheContext implements CacheContextInterface {

  use GetPoliticianFromUrlTrait;

  /**
   * @var \Drupal\pw_basic\Entity\Politician
   */
  protected $politician;

  public function __construct(CurrentRouteMatch $current_route_match) {
    $this-&gt;politician = $this-&gt;getPoliticianFromUrl();
  }


  /**
   * {@inheritdoc}
   */
  public static function getLabel() {
    return t('Politician');
  }

  /**
   * {@inheritdoc}
   */
  public function getContext() {
    $cache_context = '';
    if ($this-&gt;politician !== NULL) {
      $cache_context = $this-&gt;politician-&gt;id();
    }
    return $cache_context;
  }

  /**
   * {@inheritdoc}
   */
  public function getCacheableMetadata() {
    return new CacheableMetadata();
  }
}


Then I cleared the block plugin class from any cache logic and just added the following in template_preprocess_politician_header(), the preprocess function of the template rendered within the block:

$variables["#cache"]["contexts"][] = 'politician';


What I do not really like is the service character of the cache context classes. Why is it only possible to set the context in such a global way? Do I miss somethin? I need to use this global workaround and check for the politician from URL which makes this context not as flexible as I want it to be. Is there a way to give a variable to a cache context directly when defining it in a render array?