-
Notifications
You must be signed in to change notification settings - Fork 22
Reactive documentation #169
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
base: master
Are you sure you want to change the base?
Changes from 1 commit
f99697a
f9b8082
7734833
ba93c45
3f6bcfc
e91ef8b
8677ee5
aa05447
24f0f1a
96bd168
601a903
dca86f9
2c03ad8
aa3a79b
f46a067
aa654aa
0792564
b23bbd7
eae813e
21c77c4
33df182
582b9bd
97f8667
0e0546e
5c48637
1ef0bbf
6035ff2
d232936
33309f8
6872ea6
ad7750e
b658357
7f8ee64
d423074
cdd0b8f
88b7e16
221eaf6
cbf60f8
f768353
5d4728a
b78e19f
78548cc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,163 @@ | ||
# Command | ||
|
||
[← Back to API Reference](../README.md) | [← Back to Table of Contents](../../README.md) | ||
|
||
`Command` is a base class in Reactive Domain that implements the `ICorrelatedMessage` interface and serves as the foundation for all command messages in the system. | ||
|
||
## Overview | ||
|
||
Commands in Reactive Domain represent requests for the system to perform an action. They are part of the write side of the CQRS pattern and typically result in state changes. The `Command` base class provides common functionality for all command implementations, including correlation and causation tracking. | ||
|
||
## Class Definition | ||
|
||
```csharp | ||
public abstract class Command : ICommand, ICorrelatedMessage | ||
{ | ||
public Guid MsgId { get; } | ||
public Guid CorrelationId { get; } | ||
public Guid CausationId { get; } | ||
|
||
protected Command() | ||
{ | ||
MsgId = Guid.NewGuid(); | ||
CorrelationId = MsgId; | ||
CausationId = MsgId; | ||
} | ||
|
||
protected Command(Guid correlationId, Guid causationId) | ||
{ | ||
MsgId = Guid.NewGuid(); | ||
CorrelationId = correlationId; | ||
CausationId = causationId; | ||
} | ||
} | ||
``` | ||
|
||
## Key Features | ||
|
||
- **Message Identity**: Provides a unique `MsgId` for each command | ||
- **Correlation Tracking**: Implements `ICorrelatedMessage` for tracking related messages | ||
- **Immutability**: Ensures commands are immutable after creation | ||
- **Type Safety**: Provides a type-safe base for all command implementations | ||
|
||
## Usage | ||
|
||
### Defining a Command | ||
|
||
To create a new command type, inherit from the `Command` base class: | ||
|
||
```csharp | ||
public class CreateAccount : Command | ||
{ | ||
public readonly Guid AccountId; | ||
public readonly string AccountNumber; | ||
public readonly string CustomerName; | ||
|
||
public CreateAccount(Guid accountId, string accountNumber, string customerName) | ||
: base() | ||
{ | ||
AccountId = accountId; | ||
AccountNumber = accountNumber; | ||
CustomerName = customerName; | ||
} | ||
|
||
// Constructor for correlated commands | ||
public CreateAccount(Guid accountId, string accountNumber, string customerName, | ||
Guid correlationId, Guid causationId) | ||
: base(correlationId, causationId) | ||
{ | ||
|
||
AccountId = accountId; | ||
AccountNumber = accountNumber; | ||
CustomerName = customerName; | ||
} | ||
} | ||
``` | ||
|
||
### Using MessageBuilder with Commands | ||
|
||
It's recommended to use the `MessageBuilder` factory to create commands with proper correlation: | ||
|
||
```csharp | ||
// Create a new command that starts a correlation chain | ||
var createCommand = MessageBuilder.New(() => new CreateAccount( | ||
Guid.NewGuid(), | ||
"ACC-123", | ||
"John Doe" | ||
)); | ||
|
||
// Create a command from an existing message | ||
var depositCommand = MessageBuilder.From(createCommand, () => new DepositFunds( | ||
((CreateAccount)createCommand).AccountId, | ||
100.00m | ||
)); | ||
|
||
``` | ||
|
||
### Handling Commands | ||
|
||
Commands are typically handled by command handlers: | ||
|
||
```csharp | ||
public class CreateAccountHandler : ICommandHandler<CreateAccount> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is atypical. A class that handles commands will typically implement |
||
{ | ||
private readonly ICorrelatedRepository _repository; | ||
|
||
public CreateAccountHandler(ICorrelatedRepository repository) | ||
{ | ||
_repository = repository; | ||
} | ||
|
||
public void Handle(CreateAccount command) | ||
{ | ||
var account = new Account(command.AccountId, command); | ||
_repository.Save(account, command); | ||
} | ||
} | ||
``` | ||
|
||
## Integration with Aggregates | ||
|
||
Commands are used to modify aggregates, which then produce events: | ||
|
||
```csharp | ||
public class Account : AggregateRoot | ||
{ | ||
public Account(Guid id, ICorrelatedMessage source) : base(id) | ||
{ | ||
Apply(MessageBuilder.From(source, () => new AccountCreated(id, source.CorrelationId, source.MsgId))); | ||
|
||
} | ||
|
||
public void Deposit(decimal amount, ICorrelatedMessage source) | ||
{ | ||
Apply(MessageBuilder.From(source, () => new FundsDeposited(Id, amount))); | ||
} | ||
} | ||
``` | ||
|
||
## Best Practices | ||
|
||
1. **Immutable Commands**: Make all command properties read-only | ||
2. **Descriptive Names**: Use verb-noun naming convention (e.g., `CreateAccount`, `DepositFunds`) | ||
3. **Minimal Data**: Include only the data needed to perform the action | ||
4. **Use MessageBuilder**: Always use `MessageBuilder` to create commands with proper correlation | ||
5. **Validation**: Validate commands before processing them | ||
|
||
## Common Pitfalls | ||
|
||
1. **Mutable Commands**: Avoid mutable properties in commands | ||
2. **Business Logic in Commands**: Commands should be simple data carriers without business logic | ||
3. **Missing Correlation**: Ensure correlation information is properly maintained | ||
4. **Large Commands**: Keep commands focused and minimal | ||
|
||
## Related Components | ||
|
||
- [ICommand](./icommand.md): Interface for command messages | ||
- [ICorrelatedMessage](./icorrelated-message.md): Interface for messages with correlation information | ||
- [MessageBuilder](./message-builder.md): Factory for creating correlated messages | ||
- [ICommandHandler](./icommand-handler.md): Interface for handling commands | ||
|
||
--- | ||
|
||
**Navigation**: | ||
- [← Previous: MessageBuilder](./message-builder.md) | ||
- [↑ Back to Top](#command) | ||
- [→ Next: Event](./event.md) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This points to a URL that doesn't exist