You are correct, area emulation just sets the area, while the compiled config for DI is still loaded from the GLOBAL area. If you want to fully leverage di.xml declarations from a different area, you need to use the \Magento\Framework\ObjectManager\ObjectManager::configure method and then use the Object Manager to get the needed classes. For the configure method you will first need to obtain the compiled config for the desired area, using \Magento\Framework\App\ObjectManager\ConfigLoader\Compiled::load. Something like this:
$compiledConfigForFrontendArea = $this->compiledConfigLoader->load(Area\Magento\Framework\App\Area::AREA_FRONTEND); $this->state->emulateAreaCode(Area\Magento\Framework\App\Area::AREA_FRONTEND, function () use ($compiledConfigForFrontendArea) { //re-configure object manager with frontend area di compiled config ObjectManager::getInstance()->configure($compiledConfigForFrontendArea); //use the new context to get the class, otherwise di from global area is used and it breaks $desiredObject = ObjectManager::getInstance()->get(DesiredObject::class); }); For my specific use-case (CLI command that needed to run in the GRAPHQL area), I had to use the configure method inside the emulateAreaCode callback. It might work outside of that for your case. Also, for frontend area the system might attempt to set a theme, keep that in mind.
Hope this helps