|
1 | 1 | # Release Notes - v5.0.0 |
2 | 2 |
|
3 | 3 | ## New Architecture |
4 | | - |
5 | 4 | ``` |
6 | | -Aggregate -> Interceptor -> Middleware -> Dispatcher -> Queue <- Listener -> Middleware -> Resolver -> Handler |
| 5 | +Aggregate → Interceptor → Middleware → Dispatcher → Queue ← Listener → Resolver → Handler |
7 | 6 | ``` |
8 | 7 |
|
9 | | -### Components: |
10 | | - |
11 | | -1. **IEventMiddleware** - Custom plugins that run before/after dispatch and handling |
12 | | -2. **IEventQueue** - In-flight non-persistent queue for events |
13 | | -3. **IEventListener** - Listens to queue and triggers handling |
14 | | - |
15 | 8 | ## New Features |
16 | 9 |
|
17 | | -### 1. Event Middleware |
18 | | - |
19 | | -Custom plugins that run at various points in the event pipeline: |
20 | | - |
| 10 | +### 1. ISubscribes<TEvent> |
| 11 | +Aggregates can handle their own events: |
21 | 12 | ```csharp |
22 | | -public class MyMiddleware : IEventMiddleware |
| 13 | +public class OrderAggregate : Aggregate, ISubscribes<OrderPlaced> |
23 | 14 | { |
24 | | - public Task<bool> OnDispatchingAsync(EventContext context) { ... } |
25 | | - public Task OnDispatchedAsync(EventContext context) { ... } |
26 | | - public Task<bool> OnHandlingAsync(EventContext context) { ... } |
27 | | - public Task OnHandledAsync(EventContext context) { ... } |
| 15 | + public Task HandleAsync(OrderPlaced @event) => ...; |
| 16 | + public void PlaceOrder(decimal amount) => Raise(new OrderPlaced()); |
28 | 17 | } |
29 | 18 | ``` |
30 | 19 |
|
31 | | -**Registration:** |
| 20 | +### 2. AggregateFactory |
| 21 | +Multiple methods to create proxied aggregates: |
32 | 22 | ```csharp |
33 | | -services.AddDomainEvents(assembly); |
34 | | -services.AddSingleton<IEventMiddleware, MyMiddleware>(); |
35 | | -``` |
| 23 | +// Default constructor |
| 24 | +var order = await factory.CreateAsync<OrderAggregate>(); |
36 | 25 |
|
37 | | -### 2. Event Queue |
| 26 | +// With constructor arguments |
| 27 | +var order = await factory.CreateAsync<OrderAggregate>(logger); |
38 | 28 |
|
39 | | -In-flight non-persistent queue for events: |
40 | | - |
41 | | -```csharp |
42 | | -// Use default in-memory queue |
43 | | -services.AddDomainEvents(assembly); |
| 29 | +// From service provider (auto-resolves deps) |
| 30 | +var order = await factory.CreateFromServiceProviderAsync<OrderAggregate>(); |
44 | 31 |
|
45 | | -// Or use custom queue |
46 | | -services.AddSingleton<IEventQueue, MyCustomQueue>(); |
47 | | - |
48 | | -// Process queue |
49 | | -var dispatcher = serviceProvider.GetRequiredService<IEventDispatcher>(); |
50 | | -await dispatcher.ProcessQueueAsync(); |
| 32 | +// Wrap existing instance |
| 33 | +var order = await factory.CreateFromInstanceAsync(existingOrder); |
51 | 34 | ``` |
52 | 35 |
|
53 | | -### 3. Custom Dispatcher |
54 | | - |
55 | | -```csharp |
56 | | -services.AddDomainEventsWithDispatcher<MyCustomDispatcher>(assembly); |
57 | | -``` |
| 36 | +### 3. Event Middleware (IEventMiddleware) |
| 37 | +Pipeline hooks: `OnDispatchingAsync`, `OnDispatchedAsync`, `OnHandlingAsync`, `OnHandledAsync` |
58 | 38 |
|
59 | | -### 4. Standard EventInterceptor with Telemetry |
60 | | -The `EventInterceptor` remains standard with OpenTelemetry and logging. |
| 39 | +### 4. Event Queue (IEventQueue) |
| 40 | +In-flight non-persistent queue with subscription support |
61 | 41 |
|
62 | | -### 5. Async Handler Interface (IHandler<T>) |
63 | | -Changed from `IHandle<T>` to `IHandler<T>` with async `HandleAsync()`. |
| 42 | +### 5. Event Listener (IEventListener) |
| 43 | +Processes queued events asynchronously |
64 | 44 |
|
65 | 45 | ## Breaking Changes |
| 46 | +- `IHandle<T>` → `IHandler<T>` |
| 47 | +- `Handle()` → `HandleAsync()` returning `Task` |
66 | 48 |
|
67 | | -1. `IHandle<T>` -> `IHandler<T>` |
68 | | -2. `Handle()` -> `HandleAsync()` returning `Task` |
69 | | -3. `EventInterceptor` requires `IEventDispatcher` |
70 | | - |
71 | | -## Migration Guide |
72 | | - |
| 49 | +## Migration |
73 | 50 | ```csharp |
74 | 51 | // Before |
75 | 52 | public class Handler : IHandle<Event> { void Handle(Event e) { } } |
76 | 53 |
|
77 | 54 | // After |
78 | | -public class Handler : IHandler<Event> |
79 | | -{ |
80 | | - Task HandleAsync(Event e) => Task.CompletedTask; |
81 | | -} |
| 55 | +public class Handler : IHandler<Event> { Task HandleAsync(Event e) => Task.CompletedTask; } |
82 | 56 | ``` |
0 commit comments