diff --git a/src/Marten/Events/EventDocumentStorage.cs b/src/Marten/Events/EventDocumentStorage.cs index bef8eb2914..183c006ad8 100644 --- a/src/Marten/Events/EventDocumentStorage.cs +++ b/src/Marten/Events/EventDocumentStorage.cs @@ -223,7 +223,7 @@ public IEvent Resolve(DbDataReader reader) mapping = eventMappingForDotNetTypeName(dotnetTypeName, eventTypeName); } - var @event = deserializeEvent(mapping, reader); + var @event = mapping.ReadEventData(reader); ApplyReaderDataToEvent(reader, @event); @@ -246,7 +246,7 @@ public async Task ResolveAsync(DbDataReader reader, CancellationToken to IEvent @event; try { - @event = await deserializeEventAsync(mapping, reader, token).ConfigureAwait(false); + @event = await mapping.ReadEventDataAsync(reader, token).ConfigureAwait(false); } catch (Exception e) { @@ -280,25 +280,5 @@ private EventMapping eventMappingForDotNetTypeName(string dotnetTypeName, string return Events.EventMappingFor(type); } - - private IEvent deserializeEvent(EventMapping mapping, DbDataReader reader) - { - var data = mapping.Transformation != null? - mapping.Transformation.FromDbDataReader(_serializer, reader, 0) - : _serializer.FromJson(mapping.DocumentType, reader, 0); - - return mapping.Wrap(data); - } - - private async ValueTask deserializeEventAsync(EventMapping mapping, DbDataReader reader, - CancellationToken token) - { - // TODO -- eliminate the runtime logic here - var data = mapping.Transformation != null ? - await mapping.Transformation.FromDbDataReaderAsync(_serializer, reader, 0, token).ConfigureAwait(false) - : await _serializer.FromJsonAsync(mapping.DocumentType, reader, 0, token).ConfigureAwait(false); - - return mapping.Wrap(data); - } } } diff --git a/src/Marten/Events/EventGraph.cs b/src/Marten/Events/EventGraph.cs index 2fb79369d0..06e98839bd 100644 --- a/src/Marten/Events/EventGraph.cs +++ b/src/Marten/Events/EventGraph.cs @@ -157,7 +157,7 @@ public IEventStoreOptions Upcast( { var eventMapping = EventMappingFor(eventType); eventMapping.EventTypeName = eventTypeName; - eventMapping.Transformation = jsonTransformation; + eventMapping.JsonTransformation(jsonTransformation); return this; } @@ -169,7 +169,7 @@ Func upcast { var eventMapping = EventMappingFor(); eventMapping.EventTypeName = eventTypeName; - eventMapping.Transformation = JsonTransformations.Upcast(upcast); + eventMapping.JsonTransformation(JsonTransformations.Upcast(upcast)); return this; } @@ -186,7 +186,7 @@ Func> upcastAsync { var eventMapping = EventMappingFor(); eventMapping.EventTypeName = eventTypeName; - eventMapping.Transformation = JsonTransformations.Upcast(upcastAsync); + eventMapping.JsonTransformation(JsonTransformations.Upcast(upcastAsync)); return this; } diff --git a/src/Marten/Events/EventMapping.cs b/src/Marten/Events/EventMapping.cs index 20e84a7073..7b680eb03d 100644 --- a/src/Marten/Events/EventMapping.cs +++ b/src/Marten/Events/EventMapping.cs @@ -44,6 +44,7 @@ public abstract class EventMapping: IDocumentMapping, IEventType protected readonly EventGraph _parent; protected readonly DocumentMapping _inner; private ISqlFragment _defaultWhereFragment; + private readonly ISerializer _serializer; protected EventMapping(EventGraph parent, Type eventType) { @@ -65,21 +66,19 @@ protected EventMapping(EventGraph parent, Type eventType) filter = filter.CombineAnd(CurrentTenantFilter.Instance); } + _serializer = parent.Options.Serializer(); _defaultWhereFragment = filter; + + JsonTransformation(null); } Type IEventType.EventType => DocumentType; public string DotNetTypeName { get; set; } - /// - /// Defines the event JSON payload transformation. It transforms one event schema into another. - /// You can use it to handle the event schema versioning/migration. - /// By calling it, you tell that instead of the old CLR type, for the specific event type name, - /// you'd like to get the new CLR event type. - /// Provided functions take the deserialized object of the old event type and returns the new, mapped one. - /// - public JsonTransformation? Transformation { get; set; } + public Func ReadEventData { get; private set; } + + public Func> ReadEventDataAsync { get; private set; } IDocumentMapping IDocumentMapping.Root => this; public Type DocumentType { get; } @@ -150,6 +149,49 @@ public ISqlFragment DefaultWhereFragment() } public abstract IEvent Wrap(object data); + + /// + /// Defines the event JSON payload transformation. It transforms one event schema into another. + /// You can use it to handle the event schema versioning/migration. + /// By calling it, you tell that instead of the old CLR type, for the specific event type name, + /// you'd like to get the new CLR event type. + /// Provided functions take the deserialized object of the old event type and returns the new, mapped one. + /// + /// Json transfromation + public void JsonTransformation(JsonTransformation? jsonTransformation) + { + ReadEventData = + jsonTransformation == null + ? reader => + { + var data = _serializer.FromJson(DocumentType, reader, 0); + + return Wrap(data); + } + : reader => + { + var data = jsonTransformation.FromDbDataReader(_serializer, reader, 0); + + return Wrap(data); + } + ; + + ReadEventDataAsync = jsonTransformation == null + ? async (reader, token) => + { + var data = await _serializer.FromJsonAsync(DocumentType, reader, 0, token) + .ConfigureAwait(false); + + return Wrap(data); + } + : async (reader, token) => + { + var data = await jsonTransformation.FromDbDataReaderAsync(_serializer, reader, 0, token) + .ConfigureAwait(false); + + return Wrap(data); + }; + } } public class EventMapping: EventMapping, IDocumentStorage where T : class @@ -157,7 +199,7 @@ public class EventMapping: EventMapping, IDocumentStorage where T : class private readonly string _tableName; private Type _idType; - public EventMapping(EventGraph parent) : base(parent, typeof(T)) + public EventMapping(EventGraph parent): base(parent, typeof(T)) { var schemaName = parent.DatabaseSchemaName; _tableName = schemaName == SchemaConstants.DefaultSchema ? "mt_events" : $"{schemaName}.mt_events"; @@ -195,7 +237,8 @@ ISelector ISelectClause.BuildSelector(IMartenSession session) return new EventSelector(session.Serializer); } - IQueryHandler ISelectClause.BuildHandler(IMartenSession session, Statement topStatement, Statement currentStatement) + IQueryHandler ISelectClause.BuildHandler(IMartenSession session, Statement topStatement, + Statement currentStatement) { var selector = new EventSelector(session.Serializer); @@ -301,11 +344,7 @@ public IDeletion HardDeleteForDocument(T document, string tenantId) public override IEvent Wrap(object data) { - return new Event((T) data) - { - EventTypeName = EventTypeName, - DotNetTypeName = DotNetTypeName - }; + return new Event((T)data) { EventTypeName = EventTypeName, DotNetTypeName = DotNetTypeName }; } }