Issue #3613262: Extract shared lazy-builder placeholder logic from AiMeteringController/AiMeteringByRoleController into a trait
AiMeteringController::buildTopActiveElement()/lazyBuildTopActive() and AiMeteringByRoleController's equivalents were near-identical, differing only in the block plugin ID and cache key suffix. Extracted the shared logic into a new TopActiveLazyBuilderTrait, parameterized by block plugin ID and cache key suffix.
Closes #3613262