Skip to content

Commit 1b10274

Browse files
committed
Implements command response framework
Adds interfaces and classes for a command response framework. This change introduces `ICommandResponse` and associated classes to provide a standardized way of handling command execution results. It also updates the validation middleware to properly handle the new response types. Removes an obsolete CommandResponse file.
1 parent 79b384e commit 1b10274

4 files changed

Lines changed: 88 additions & 38 deletions

File tree

sample/Domain/Commands/CreateWidget.cs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,8 @@ public async Task<CommandResponse<string>> Execute(CreateWidgetMessage message,
2424
response += $"Name: {message.Name} message was sent and processed with Success={eventargs.Success}";
2525
};
2626

27-
await _publisher.Publish(new WidgetCreated{Name = message.Name}, cancellationToken);
27+
await _publisher.Publish(new WidgetCreated { Name = message.Name }, cancellationToken);
2828

2929
return Response.Ok(response);
3030
}
31-
}
32-
33-
public class V2
34-
{
3531
}

sample/Domain/Middleware/AsyncHandlerValidationMiddleware.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public async ValueTask InvokeAsync(
2424
context.ShouldContinue = false;
2525

2626
// For CommandResponse, create an error response
27-
if (typeof(TResponse) == typeof(CommandResponse))
27+
if (typeof(TResponse) == typeof(ICommandResponse))
2828
{
2929
context.Response = (TResponse)(object)new CommandResponse
3030
{
Lines changed: 74 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,82 @@
11
using System;
2+
using System.Reflection.Metadata.Ecma335;
23

3-
namespace CommandQuery.Framing
4+
namespace CommandQuery.Framing;
5+
6+
public interface ICommandResponse
7+
{
8+
/// <summary>
9+
/// Gets or sets a value indicating whether the operation was successful.
10+
/// </summary>
11+
bool Success { get; set; }
12+
13+
/// <summary>
14+
/// Gets or sets a message describing the result (typically used for errors).
15+
/// </summary>
16+
string Message { get; set; }
17+
18+
/// <summary>
19+
/// Gets or sets the exception that occurred, if any.
20+
/// </summary>
21+
Exception Exception { get; set; }
22+
23+
object RawData { get; }
24+
}
25+
26+
/// <summary>
27+
/// Represents the response from executing a command or query.
28+
/// </summary>
29+
public class CommandResponse : ICommandResponse
30+
{
31+
/// <summary>
32+
/// Gets or sets a value indicating whether the operation was successful.
33+
/// </summary>
34+
public bool Success { get; set; }
35+
36+
/// <summary>
37+
/// Gets or sets a message describing the result (typically used for errors).
38+
/// </summary>
39+
public string Message { get; set; }
40+
41+
/// <summary>
42+
/// Gets or sets the exception that occurred, if any.
43+
/// </summary>
44+
public Exception Exception { get; set; }
45+
46+
public object RawData => null;
47+
}
48+
49+
/// <summary>
50+
/// Represents the response from executing a command or query.
51+
/// </summary>
52+
/// <typeparam name="T">The type of data returned in the response.</typeparam>
53+
public class CommandResponse<T> : ICommandResponse
454
{
555
/// <summary>
6-
/// Represents the response from executing a command or query.
56+
/// Gets or sets a value indicating whether the operation was successful.
57+
/// </summary>
58+
public bool Success { get; set; }
59+
60+
/// <summary>
61+
/// Gets or sets the response data.
762
/// </summary>
8-
/// <typeparam name="T">The type of data returned in the response.</typeparam>
9-
public class CommandResponse<T>
63+
private T _data;
64+
65+
public T Data
1066
{
11-
/// <summary>
12-
/// Gets or sets a value indicating whether the operation was successful.
13-
/// </summary>
14-
public bool Success { get; set; }
15-
16-
/// <summary>
17-
/// Gets or sets the response data.
18-
/// </summary>
19-
public T Data { get; set; }
20-
21-
/// <summary>
22-
/// Gets or sets a message describing the result (typically used for errors).
23-
/// </summary>
24-
public string Message { get; set; }
25-
26-
/// <summary>
27-
/// Gets or sets the exception that occurred, if any.
28-
/// </summary>
29-
public Exception Exception { get; set; }
67+
get => _data;
68+
set => _data = value;
3069
}
70+
71+
/// <summary>
72+
/// Gets or sets a message describing the result (typically used for errors).
73+
/// </summary>
74+
public string Message { get; set; }
75+
76+
/// <summary>
77+
/// Gets or sets the exception that occurred, if any.
78+
/// </summary>
79+
public Exception Exception { get; set; }
80+
81+
public object RawData => _data;
3182
}

test/CommandTests/DomainTests/CanGetMessageFromDomainPublisherTest.cs

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
using System;
2-
using System.Threading;
3-
using System.Threading.Tasks;
4-
using CommandQuery.Framing;
1+
using CommandQuery.Framing;
52
using Microsoft.Extensions.DependencyInjection;
63
using Shouldly;
74

@@ -23,11 +20,17 @@ public async Task can_get_message_from_domain_publisher()
2320
var sentCnt = 0;
2421
var resultCnt = 0;
2522

23+
if (publisher is null)
24+
{
25+
throw new Exception("Publisher is null");
26+
}
27+
2628
publisher.MessageSent += (sender, args) => sentCnt++;
2729

2830
publisher.MessageResult += (sender, args) => resultCnt++;
2931

30-
await publisher.Publish(new TestDomainEventMessage(), new CancellationToken());
32+
var cancellationToken = CancellationToken.None;
33+
await publisher.Publish(new TestDomainEventMessage(), cancellationToken);
3134

3235
sentCnt.ShouldBe(2);
3336
resultCnt.ShouldBe(2);
@@ -40,11 +43,11 @@ public class TestDomainEventMessage
4043

4144
public class TestDomainEvent : IDomainEvent<TestDomainEventMessage>
4245
{
43-
public event EventHandler<DomainEventArgs> OnComplete;
46+
public event EventHandler<DomainEventArgs>? OnComplete;
4447

4548
public async Task Execute(TestDomainEventMessage message)
4649
{
47-
OnComplete(this,
50+
OnComplete?.Invoke(this,
4851
new DomainEventArgs
4952
{
5053
Message = "Completed",
@@ -57,11 +60,11 @@ public async Task Execute(TestDomainEventMessage message)
5760

5861
public class TestDomainEventTwo : IDomainEvent<TestDomainEventMessage>
5962
{
60-
public event EventHandler<DomainEventArgs> OnComplete;
63+
public event EventHandler<DomainEventArgs>? OnComplete;
6164

6265
public async Task Execute(TestDomainEventMessage message)
6366
{
64-
OnComplete(this,
67+
OnComplete?.Invoke(this,
6568
new DomainEventArgs
6669
{
6770
Message = "Completed",

0 commit comments

Comments
 (0)