One of the powers of using the access handler is that we can make it aware of the service container and inject whatever services we might need to determine access. However, it's not immediately clear how you can do this, so we'll break it down here.
The first thing we will need is to have our access handler implement the \Drupal\core\Entity\EntityHandlerInterface. Note that this applies in the same way to the other types of handlers, not just access-related. This interface has one method, which will receive the container and the entity type definition: createInstance().
Knowing this, the rest is very similar to how we injected services into Controllers and Forms using the create() method, which only takes the container as argument, or into plugins, which also takes some plugin information:
/** * @var \Drupal\Core\Entity\EntityTypeManagerInterface */ protected $entityTypeManager; /** * ProductAccessControlHandler constructor. * * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type * @param \Drupal\Core\Entity\EntityTypeManager $entityTypeManager */ public function __construct(EntityTypeInterface $entity_type, EntityTypeManagerInterface $entityTypeManager) { parent::__construct($entity_type); $this->entityTypeManager = $entityTypeManager; } /** * {@inheritdoc} */ public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) { return new static( $entity_type, $container->get('entity_type.manager') ); }
And the new use statements:
use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; use Symfony\Component\DependencyInjection\ContainerInterface;
With this, we have injected the entity type manager into the access handler, and if we want, we can use it. Of course, if we don't need it, we should not inject it in the first place.