Skip to content

Commit

Permalink
feat/refactor: move the boxing up a level for annotated commands
Browse files Browse the repository at this point in the history
this allows pattern matching on IEntityAnnotation<> where the actual command type can be used as the generic parameter.

before you would have to check IEntityAnnotation<...>.Data is <CommandType>; now you can check IEntityAnnotation<CommandType>
  • Loading branch information
the-avid-engineer committed Apr 6, 2022
1 parent 12cc8da commit 2c70b6c
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 38 deletions.
28 changes: 19 additions & 9 deletions src/EntityDb.Common/Annotations/EntityAnnotation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using EntityDb.Abstractions.Transactions;
using EntityDb.Abstractions.Transactions.Steps;
using EntityDb.Abstractions.ValueObjects;
using System;

namespace EntityDb.Common.Annotations;

Expand All @@ -14,16 +15,25 @@ internal record EntityAnnotation<TData>
TData Data
) : IEntityAnnotation<TData>
{
public static EntityAnnotation<TData> CreateFrom(ITransaction transaction, ITransactionStep transactionStep,
TData data)
public static IEntityAnnotation<TData> CreateFromBoxedData
(
Id transactionId,
TimeStamp transactionTimeStamp,
Id entityId,
VersionNumber entityVersionNumber,
object boxedData
)
{
return new
var dataAnnotationType = typeof(EntityAnnotation<>).MakeGenericType(boxedData.GetType());

return (IEntityAnnotation<TData>)Activator.CreateInstance
(
transaction.Id,
transaction.TimeStamp,
transactionStep.EntityId,
transactionStep.EntityVersionNumber,
data
);
dataAnnotationType,
transactionId,
transactionTimeStamp,
entityId,
entityVersionNumber,
boxedData
)!;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,14 @@ protected override async Task NotifyAsync(ITransaction transaction)

var projection = previousProjection;

var annotatedCommand = EntityAnnotation<object>.CreateFrom(transaction, appendCommandTransactionStep, appendCommandTransactionStep.Command);
var annotatedCommand = EntityAnnotation<object>.CreateFromBoxedData
(
transaction.Id,
transaction.TimeStamp,
appendCommandTransactionStep.EntityId,
appendCommandTransactionStep.EntityVersionNumber,
appendCommandTransactionStep.Command
);

projection = projection.Reduce(annotatedCommand);

Expand Down
6 changes: 4 additions & 2 deletions src/EntityDb.MongoDb/Extensions/DocumentQueryExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;

Expand Down Expand Up @@ -104,19 +105,20 @@ public static async Task<IEntityAnnotation<TData>[]> GetEntityAnnotation<TDocume
CancellationToken cancellationToken
)
where TDocument : IEntityDocument
where TData : notnull
{
var documents = await documentQuery.Execute(mongoSession, NoDocumentIdProjection, cancellationToken);

return documents
.Select(document => new EntityAnnotation<TData>
.Select(document => EntityAnnotation<TData>.CreateFromBoxedData
(
document.TransactionId,
document.TransactionTimeStamp,
document.EntityId,
document.EntityVersionNumber,
envelopeService.Reconstruct<TData>(document.Data)
))
.ToArray<IEntityAnnotation<TData>>();
.ToArray();
}

public static async Task<TData[]> GetData<TDocument, TData>
Expand Down
19 changes: 7 additions & 12 deletions test/EntityDb.Common.Tests/Implementations/Entities/TestEntity.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
using EntityDb.Common.Entities;
using System;
using System.Linq;
using System.Threading;
using EntityDb.Abstractions.Reducers;
using EntityDb.Abstractions.ValueObjects;
using EntityDb.Common.Snapshots;
using EntityDb.Common.Tests.Implementations.Commands;
using EntityDb.Common.Tests.Implementations.Snapshots;

namespace EntityDb.Common.Tests.Implementations.Entities;
Expand Down Expand Up @@ -40,19 +42,12 @@ public VersionNumber GetVersionNumber()

public TestEntity Reduce(object[] commands)
{
var newEntity = this;

foreach (var command in commands)
return commands.Aggregate(this, (previousEntity, nextCommand) => nextCommand switch
{
if (command is not IReducer<TestEntity> reducer)
{
throw new NotImplementedException();
}

newEntity = reducer.Reduce(newEntity);
}

return newEntity;
DoNothing doNothing => doNothing.Reduce(previousEntity),
Count count => count.Reduce(previousEntity),
_ => throw new NotSupportedException()
});
}

public static AsyncLocal<Func<TestEntity, TestEntity?, bool>?> ShouldReplaceLogic { get; } = new();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
using System;
using System.Linq;
using System.Threading;
using EntityDb.Abstractions.Annotations;
using EntityDb.Abstractions.Reducers;
using EntityDb.Abstractions.ValueObjects;
using EntityDb.Common.Projections;
using EntityDb.Common.Snapshots;
using EntityDb.Common.Tests.Implementations.Commands;
using EntityDb.Common.Tests.Implementations.Snapshots;

namespace EntityDb.Common.Tests.Implementations.Projections;
Expand Down Expand Up @@ -34,21 +36,12 @@ public VersionNumber GetEntityVersionNumber(Id entityId)

public OneToOneProjection Reduce(params IEntityAnnotation<object>[] annotatedCommands)
{
var newProjection = this;

foreach (var annotatedCommand in annotatedCommands)
return annotatedCommands.Aggregate(this, (previousProjection, nextAnnotatedCommand) => nextAnnotatedCommand switch
{
var command = annotatedCommand.Data;

if (command is not IReducer<OneToOneProjection> reducer)
{
throw new NotImplementedException();
}

newProjection = reducer.Reduce(newProjection);
}

return newProjection;
IEntityAnnotation<DoNothing> doNothing => doNothing.Data.Reduce(previousProjection),
IEntityAnnotation<Count> count => count.Data.Reduce(previousProjection),
_ => throw new NotSupportedException()
});
}

public static AsyncLocal<Func<OneToOneProjection, OneToOneProjection?, bool>?> ShouldReplaceLogic { get; } = new();
Expand Down

0 comments on commit 2c70b6c

Please sign in to comment.