using System.Text.Json.Serialization;
[JsonPolymorphic(TypeDiscriminatorPropertyName = "EventType")]
[JsonDerivedType(typeof(EventEnvelopeAlpha), typeDiscriminator: nameof(EventAlpha))]
[JsonDerivedType(typeof(EventEnvelopeBravo), typeDiscriminator: nameof(EventBravo))]
public class EventEnvelope
public Guid EventId { get; init; } = Guid.NewGuid();
public string EventSource { get; init; } = "Event.Source";
public DateTime EventDate { get; init; } = DateTime.UtcNow;
public class EventEnvelopeAlpha : EventEnvelope
public EventAlpha EventData { get; init; }
public class EventEnvelopeBravo : EventEnvelope
public EventBravo EventData { get; init; }
public abstract class EventData
public string SchemaVersion { get; init; } = "1.0";
public class EventAlpha : EventData
public string PropertyZulu { get; init; }
public class EventBravo : EventData
public string PropertyYankee { get; init; }
public static void Main()
var evt = new EventEnvelopeBravo
EventData = new EventBravo { PropertyYankee = "foo" }
var serialized = JsonSerializer.Serialize(evt);
var deserialized = JsonSerializer.Deserialize<EventEnvelope>(serialized);
Console.WriteLine(serialized);
if (deserialized is EventEnvelopeBravo e)
Console.WriteLine(e.EventData.PropertyYankee);