Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Event Type Mapping improvements #190

Merged
merged 4 commits into from
Feb 17, 2023
Merged

Event Type Mapping improvements #190

merged 4 commits into from
Feb 17, 2023

Conversation

oskardudycz
Copy link
Owner

Made slight improvements to EventTypeMapper, allowing it to be injected by DI

@@ -26,7 +26,7 @@ static EventStoreDBSerializer()
public static object? Deserialize(this ResolvedEvent resolvedEvent)
{
// get type
var eventType = EventTypeMapper.ToType(resolvedEvent.Event.EventType);
var eventType = EventTypeMapper.Instance.ToType(resolvedEvent.Event.EventType);
Copy link
Contributor

@bartelink bartelink Dec 8, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm I find it a bit disturbing that this has state and has not gone to the singleton pattern too. I'd pick either static or stateful and wired through DI throughout in order to allow one to set up multiple event mapping policies with different json converters etc. (The logical conclusion of this is of course that the mapping process should be managed at the category level, not a global level)

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See, I changed that from static class because of your comment :P Tbt, I don't want to push the serializer as a dependency, I don't want it to be replaceable, but the essential part of the event store. If I put it as a parameter, then I'd push it also forward everywhere. This is really invasive in the parts where I'm musing more functional composition and redundant. I'm happy to revise the last changes.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure what the exact comment was, but the bottom line is that if it's stateful, then you need to decide

  • if there can be multiple instances. If that's a nice to have that some people will want, baking in Singleton pattern sends the wrong message, whereas static is clear enough about the current impl not being generalised in that direction yet
  • whether state can be written concurrently

};
}

public static ShoppingCart Default() =>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

never a good pattern. should not be in Domain. Fine if you want it as a helper in tests, but put it there then


using static ShoppingCartEvent;

public abstract class StronglyTypedValue<T>: IEquatable<StronglyTypedValue<T>> where T : notnull
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

interesting related things https://github.com/jet/equinox/blob/ebca2357c12f5ef46bbbba6e417d153272798285/samples/Store/Domain/Infrastructure.fs#L8

(I tend not to get into using these - I just use FSharp.UMX instead of all this...

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll just reference it to https://event-driven.io/en/using_strongly_typed_ids_with_marten/. It's more about showing how this can be done, but I also wouldn't suggest doing that. In general, I think that strongly typed ids is quite often overkill :P

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 I guess the main thing is to demonstrate it once, and ideally not mixed with something else (do as I say, not as I do :D)


protected StronglyTypedValue(T value) => Value = value;

public override string ToString() => Value.ToString()!;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that renders Guids with dashes etc, which can end up very messy - might be worth considering how to model where you want e.g. cart id not to have embedded dashes

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, still, as this is an illustration then, I'm not sure if it includes the specific format, then the reader might be wondering why I did that. Thoughts?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For me the problem is that leaning on the default ToString of a type when you're trying to represent something as typesafe is a hole - I'd tend to either have a base StringId class with explicit translations, or leave abstract methods etc. (see the other types I linked for ways to remove that ambiguity/implicitness).
You can still do some CreateDefault helper that plugs in the ToString explicitly afterwards

I guess if you can take Guids out of the picture entirely, then the issue of how to render them is off the table too...

productItems
.Union(new[] { new KeyValuePair<ProductId, Quantity>(productItem.ProductId, productItem.Quantity) })
.GroupBy(ks => ks.Key)
.ToDictionary(ks => ks.Key, ps => Quantity.Parse((uint)ps.Sum(x => x.Value.Value)));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would be much clearer to have an AddOrUpdate helper a la ConcurrentDictionary and then have 2 simple bits of code that either add to current value or insert the value - thats why its a dictionary isnt it?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense, although then I'd need to explain it in the article 😅

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think they'd survive - you want to tease them into looking at the code on the github!

? new KeyValuePair<ProductId, Quantity>(p.Key,
Quantity.Parse(p.Value.Value - productItem.Quantity.Value))
: p)
.Where(p => p.Value > Quantity.Parse(0))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this select/where should be a TryGetValue with a default

@oskardudycz oskardudycz marked this pull request as ready for review February 17, 2023 08:15
@oskardudycz oskardudycz merged commit a1f5d91 into main Feb 17, 2023
@oskardudycz oskardudycz deleted the event_type_mapping branch February 17, 2023 08:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants