Every imperative operation in the system represents a
command in CQRS. A Command is simply a DTO-type of object that contains the
data necessary to make one specific change to the state of the system. The
service method that accepts a command does not returns any values. In case of
WCF services, if the command execution failed, a fault contract exception is
thrown. The method that accepts the command is responsible for validating the
command via a command validator object (remember SRP :)) before passing it to a
handler object to execute the command.
Below is an example of a DTO that encapsulates the command
information in our sample. Note that the commands have an Identity object in
our sample.
public class RespondToRsvpCommand : ICommand
{
public Guid RsvpReferenceId { get; set; }
public bool Response { get; set; }
public override string ToString()
{
return "Respond to RSVP";
}
}
The command handlers are responsible for executing the commands.
You can normally group commands to an aggregate in a command handler as given
below.
public class RsvpCommandHandler : ICommandHandler<RespondToRsvpCommand>, ICommandHandler<ConfigureRsvpCommand>,
IDependencyResolver
{
[InjectionConstructor]
public RsvpCommandHandler()
{
ResolveDependencies();
}
private ICommandValidator<RespondToRsvpCommand> RespondToRsvpCommandValidator { get; set; }
private ICommandValidator<ConfigureRsvpCommand> ConfigureRsvpCommandValidator { get; set; }
public void Process(RespondToRsvpCommand command)
{
//RSVP
processing logic goes here
}
public bool Validate(ConfigureRsvpCommand command)
{
return true;
}
public void Process(ConfigureRsvpCommand command)
{
//throw
new NotImplementedException();
}
public bool IsValid(RespondToRsvpCommand command)
{
return RespondToRsvpCommandValidator.Validate(command);
}
public bool IsValid(ConfigureRsvpCommand command)
{
return ConfigureRsvpCommandValidator.Validate(command);
}
public void ResolveDependencies()
{
RespondToRsvpCommandValidator = Container.Current.Resolve<ICommandValidator<RespondToRsvpCommand>>();
ConfigureRsvpCommandValidator = Container.Current.Resolve<ICommandValidator<ConfigureRsvpCommand>>();
}
}
As you can see, I've used the ICommandValidator instances to
validate the respective commands in the context. I've also used the unity
dependency container as my dispatcher object to dispatch the respective command
handlers.
Next : Events
No comments:
Post a Comment