Skip to content

Commit 4eb1363

Browse files
committed
- Checkpoint: Refactor Saga Code
1 parent ec17403 commit 4eb1363

File tree

18 files changed

+164
-248
lines changed

18 files changed

+164
-248
lines changed

src/SourceFlow.ConsoleApp/Sagas/AccountSaga.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
namespace SourceFlow.ConsoleApp.Sagas
66
{
77
public class AccountSaga : BaseSaga<BankAccount>,
8-
IEventHandler<AccountCreated>,
9-
IEventHandler<MoneyDeposited>,
10-
IEventHandler<MoneyWithdrawn>,
11-
IEventHandler<AccountClosed>
8+
ISagaHandler<AccountCreated>,
9+
ISagaHandler<MoneyDeposited>,
10+
ISagaHandler<MoneyWithdrawn>,
11+
ISagaHandler<AccountClosed>
1212
{
1313
public async Task Handle(AccountCreated @event)
1414
{

src/SourceFlow/BaseAggregate.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,12 @@ protected Task PublishAsync(IEvent @event)
4747
if (@event == null)
4848
throw new ArgumentNullException(nameof(@event));
4949

50+
if (@event.Entity?.Id == null)
51+
throw new InvalidOperationException(nameof(@event) + "requires source entity id");
52+
53+
if (@event.Entity.Type == null)
54+
@event.Entity.Type = typeof(TAggregate);
55+
5056
return busPublisher.Publish(@event);
5157
}
5258
}

src/SourceFlow/BaseSaga.cs

Lines changed: 11 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
using System;
2-
using System.Collections.Generic;
3-
using System.Linq;
42
using System.Threading.Tasks;
53
using Microsoft.Extensions.Logging;
64

@@ -13,11 +11,6 @@ namespace SourceFlow
1311
public abstract class BaseSaga<TAggregateEntity> : ISaga<TAggregateEntity>
1412
where TAggregateEntity : class, IEntity
1513
{
16-
/// <summary>
17-
/// Collection of event handlers registered with this saga.
18-
/// </summary>
19-
public ICollection<SagaHandler> Handlers { get; } = new List<SagaHandler>();
20-
2114
/// <summary>
2215
/// The bus publisher used to publish events.
2316
/// </summary>
@@ -38,23 +31,6 @@ public abstract class BaseSaga<TAggregateEntity> : ISaga<TAggregateEntity>
3831
/// </summary>
3932
protected BaseSaga()
4033
{
41-
RegisterHandlers();
42-
}
43-
44-
/// <summary>
45-
/// Registers all event handlers for the event types that this saga handles.
46-
/// </summary>
47-
private void RegisterHandlers()
48-
{
49-
var interfaces = this.GetType().GetInterfaces();
50-
foreach (var iface in interfaces)
51-
{
52-
if (iface.IsGenericType &&
53-
iface.GetGenericTypeDefinition() == typeof(IEventHandler<>))
54-
{
55-
Handlers.Add(new SagaHandler(iface.GetGenericArguments()[0], (IEventHandler)this));
56-
}
57-
}
5834
}
5935

6036
/// <summary>
@@ -63,12 +39,12 @@ private void RegisterHandlers()
6339
/// <param name="instance"></param>
6440
/// <param name="eventType"></param>
6541
/// <returns></returns>
66-
private static bool IsGenericEventHandler(IEventHandler instance, Type eventType)
42+
internal static bool CanHandle(ISaga instance, Type eventType)
6743
{
6844
if (instance == null || eventType == null)
6945
return false;
7046

71-
var handlerType = typeof(IEventHandler<>).MakeGenericType(eventType);
47+
var handlerType = typeof(ISagaHandler<>).MakeGenericType(eventType);
7248
return handlerType.IsAssignableFrom(instance.GetType());
7349
}
7450

@@ -80,30 +56,19 @@ private static bool IsGenericEventHandler(IEventHandler instance, Type eventType
8056
/// <returns></returns>
8157
async Task ISaga.Handle<TEvent>(TEvent @event)
8258
{
83-
var tasks = new List<Task>();
84-
85-
foreach (var handler in Handlers)
86-
{
87-
if (!handler.EventType.Equals(@event.GetType()) ||
88-
!IsGenericEventHandler(handler.Handler, @event.GetType()))
89-
continue;
90-
91-
var method = typeof(IEventHandler<>)
92-
.MakeGenericType(@event.GetType())
93-
.GetMethod(nameof(IEventHandler<TEvent>.Handle));
94-
95-
var task = (Task)method.Invoke(handler.Handler, new object[] { @event });
59+
if (!CanHandle(this, @event.GetType()))
60+
return;
9661

97-
logger?.LogInformation("Action=Saga_Handled, Event={Event}, Aggregate={Aggregate}, SequenceNo={No}, Saga={Saga}, Handler:{Handler}",
98-
@event.GetType().Name, @event.Entity.Type.Name, @event.SequenceNo, this.GetType().Name, method.Name);
62+
var method = typeof(ISagaHandler<>)
63+
.MakeGenericType(@event.GetType())
64+
.GetMethod(nameof(ISagaHandler<TEvent>.Handle));
9965

100-
tasks.Add(task);
101-
}
66+
var task = (Task)method.Invoke(this, new object[] { @event });
10267

103-
if (!tasks.Any())
104-
return;
68+
logger?.LogInformation("Action=Saga_Handled, Event={Event}, Aggregate={Aggregate}, SequenceNo={No}, Saga={Saga}, Handler:{Handler}",
69+
@event.GetType().Name, @event.Entity.Type.Name, @event.SequenceNo, this.GetType().Name, method.Name);
10570

106-
await Task.WhenAll(tasks);
71+
await Task.Run(() => task);
10772
}
10873

10974
/// <summary>

0 commit comments

Comments
 (0)