-
Notifications
You must be signed in to change notification settings - Fork 29
/
OrderSqlRepository.EventsSourcing.cs
executable file
·56 lines (49 loc) · 2.13 KB
/
OrderSqlRepository.EventsSourcing.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
using JetBrains.Annotations;
using Marten;
using MyCompany.ECommerce.Sales.Commons;
using MyCompany.ECommerce.Sales.Integrations.RiskManagement;
using MyCompany.ECommerce.TechnicalStuff;
namespace MyCompany.ECommerce.Sales.Orders;
public static partial class OrderSqlRepository
{
[UsedImplicitly]
public partial class EventsSourcing(RiskManagement riskManagement, IDocumentSession session)
: Order.Factory(riskManagement), Order.Repository
{
public static readonly IEnumerable<(Type Type, string Name)> Events = new[]
{
(typeof(Order.CreatedFromOffer), "Order.CreatedFromOffer"),
(typeof(Order.ProductAmountAdded), "Order.ProductAmountAdded"),
(typeof(Order.PricesConfirmed), "Order.PricesConfirmed"),
(typeof(Order.Placed), "Order.Placed")
};
private readonly Dictionary<OrderId, long> _orderVersions = new();
protected override Order.Data CreateData(OrderId id, Money maxTotalCost) => new Data { Id = id };
public async Task<Order> GetBy(OrderId id)
{
if (_orderVersions.ContainsKey(id))
throw new DesignError(SameAggregateRestoredMoreThanOnce);
var events = await session.Events.FetchStreamAsync(id.Value);
var version = events.Count > 0 ? events[^1].Version : 0;
_orderVersions.Add(id, version);
var orderEvents = events
.Select(e => e.Data)
.Cast<Order.Event>();
var order = Order.RestoreFrom(new Data { Id = id });
foreach (var orderEvent in orderEvents)
orderEvent.Apply(order);
return order;
}
public async Task Save(Order order)
{
// TODO: event versioning
session.Events.Append(
order.Id.Value,
CalculateExpectedVersionFor(order),
order.NewEvents);
await session.SaveChangesAsync();
}
private long CalculateExpectedVersionFor(Order order) =>
(_orderVersions.TryGetValue(order.Id, out var version) ? version : 0) + order.NewEvents.Count;
}
}