How do I deal with serialization unsetting object members? Let's say I have a plugin that uses an injected service to get some object. The object is expensive but can't be serialized, so I can only store it as long as my plugin instance lives.

To keep it away from DependencySerializationTrait, I declare it private.

class MyPlugin extends SomePluginBase implements ContainerFactoryPluginInterface {

  /**
   * @var \Drupal\module\ServiceInterface
   */
  protected $service;

  /**
   * @var \Drupal\module\SomeUnserializableThing
   */
  private $data;

  /**
   * Constructor
   *
   * @param \Drupal\module\ServiceInterface $service
   */
  public __construct(ServiceInterface $service) {
    $this-&gt;service = $service;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static($container-&gt;get('my_module.service'));
  }

  /**
   * {@inheritdoc}
   */
  public getData() {
    if (!$this-&gt;data) {
      $this-&gt;data = $this-&gt;service-&gt;loadData();
    }
    return $this-&gt;data;
  }

}


Unfortunately, after serializing and unserializing the instance doesn't have any reference to the member - not even NULL. What happens in ::getData is that the !$this-&gt;data check causes an E_NOTICE error even though that variable is explicitly defined in the class.

Are we back to the dark age of isset() and empty() here, or do I need to implement __wakeup() for all my classes to explicitly initialize their private members to NULL? Both seem unpalatable...
__sleep() works by returning properties that need to be serialized. A private property is invisible, won't show up in $vars and therefore is also not serialized and just silently dropped.

Either don't use private (it only serialized services, I assume data is not a service), or override __sleep(), call the parent and then add data to the list of properties to be serialized.