title: Delphi: superobject serialization custom converter/inverter
body: <p>I'd like to serialize objects and records to send them and restore on a remote endpoint.
  There is the shared objects declaration unit for a local and remote end. </p>
  
  <p>I has a record with a field containing different records as JSON Object:</p>
  
  <pre><code>TPmMessage = record
    CorrelationId: TGUID;
    BatchId: TGUID;
    MessageName: string; 
    Data: ISuperObject; // TAlarms, TCommand record and etc. can be inside as JSON object
  end;
  </code></pre>
  
  <h2>CASE 1</h2>
  
  <p><strong>I need to write a Type name (TRttiType.QualifiedName) in a JSON object for the Data field for deserialization on other side.</strong></p>
  
  <p>An example structure:</p>
  
  <pre><code>  TDeviceInfo = record
      DeviceType: string;
      DeviceIp: string;
    end;
  
    TAlarmLocation = record
      Name: string;
      rack: Word;
      slot: Word;
      port: Word;
    end;
  
    TAlarmInfo = record
      AlarmType: string;
      Severity: string;
      ConditionType: string;
      Datetime: TDateTime;
      Location: TAlarmLocation;
    end;
  
    TAlarm = record
      DeviceInfo: TDeviceInfo;
      Alarm: TAlarmInfo;
    end;
  
    TAlarmsList = array of TAlarmInfo;
  </code></pre>
  
  <p>Usage:</p>
  
  <pre><code>var
    msg: TPmMessage;
    als: TAlarms;
    ctx: TSuperRttiContext;
    JsonText: string;
  begin
    ctx := TSuperRttiContext.Create;
    try
    SetLength(als,2);
    // init array of als
    ...
    // init TPmMessage Fields
    ...
    // serialize TAlarms
    msg.Data := ctx.AsJson&lt;TAlarms&gt;(als);
    // serialize TPmMessage
    JsonText := ctx.AsJson&lt;TPmMessage&gt;(msg).AsString;
    ...
    // Restore record from JSON object
    msg := ctx.AsType&lt;TPmMessage&gt;(SO(JsonText));
    ...
    finally
      ctx.Free;
    end;
  end;
  </code></pre>
  
  <p>After restore I get an TPmMessage, but I don't know what type in the Data JSON object.</p>
  
  <h2>CASE 2</h2>
  
  <p>In case 1 I don't know the type of the Data JSON object. So I added the <em>DataObjectType</em> field with QualifiedName as value.</p>
  
  <p><strong>In that case I make another structure for seralization:</strong></p>
  
  <pre><code>  TPmMessageData = record
      DataObjectType: string;
      DataObject: ISuperObject;
    end;
  
    TPmMessage = record
      Source: string;
      CorrelationId: TGUID;
      BatchId: TGUID;
      MessageName: string;
      Data: TPmMessageData;
    end;
  </code></pre>
  
  <p>This structure serialized correctly with code:</p>
  
  <pre><code>var 
    msg: TPmMessage;
    ti: PTypeInfo;
    uals: TAlarms;
  begin
    {fill Alarms array}
    ti := TypeInfo(TAlarms);
    msg.Data.DataObjectType := ctx.Context.GetType(ti).QualifiedName;
    msg.Data.DataObject := ctx.AsJson&lt;TAlarms&gt;(uals);
  end;
  </code></pre>
  
  <p><em>DataObject: ISuperObject</em> also serialised well.</p>
  
  <p>A question is How to deserialize the <em>DataObject</em>?</p>
  
  <p>I thought that it's possioble to use</p>
  
  <pre><code>{var DataType: TRttiType;}
  DataType := ctx.Context.FindType(DecodedMsg.Data.DataObjectType);
  uals := ctx.AsJson&lt;DataType&gt;(DecodedMsg.Data.DataObject);
  </code></pre>
  
  <p><em><strong>But the Method 'AsType' requires explicit type argument.</em></strong></p>
  
  <p>So I think to use <em>case</em> to set the correct type is the only way.</p>
  
  <p>How to serialize/deserialise by using superobject beter? </p>
  
  <p>Could you suggest me a better structure for the messages instead of this?</p>