I have implemented a CQRS approach in my application heavily influenced by this fantastic article: https://cuttingedge.it/blogs/steven/pivot/entry.php?id=9. My code for the commands and handlers is set it up identically to the article and that part is working well. My problem comes in when I try to implement a decorator class to handle validation of the command. The simple command handling interfaces look like this:
public interface ICommand
{
}
public interface ICommandHandler<TCommand>
{
void Handle(TCommand command);
}
Then for the validation decorator I have:
public class ValidationCommandHandlerDecorator<TCommand> : ICommandHandler<TCommand> where TCommand : CommandBase
{
private readonly ICommandHandler<TCommand> _decoratedCommandHandler;
private readonly ICommandValidator<TCommand> _commandValidator;
public ValidationCommandHandlerDecorator(ICommandHandler<TCommand> decoratedCommandHandler, ICommandValidator<TCommand> commandValidator)
{
_decoratedCommandHandler = decoratedCommandHandler;
_commandValidator = commandValidator;
}
public void Handle(TCommand command)
{
if (_commandValidator != null)
{
var validationResult = _commandValidator.Validate(command);
if (validationResult != null)
{
command.Success = false;
command.Errors = validationResult;
return;
}
}
_decoratedCommandHandler.Handle(command);
command.Success = true;
}
}
Which makes use of an interface to define the validators:
public interface ICommandValidator<TCommand>
{
IEnumerable<string> Validate(TCommand command);
}
And CommandBase
is a simple base class that allows me to store the success or failure of the command and the errors that occurred if it failed. I prefer this method as an alternative to throwing an exception. All commands would inherit this base class.
public abstract class CommandBase : ICommand
{
public bool Success { get; set; }
public IEnumerable<string> Errors { get; set; }
}
And this is all wired up to the IoC container within the structure map registry:
public class CommandRegistry : Registry
{
public CommandRegistry()
{
Scan(s =>
{
s.AssemblyContainingType<CommandBase>();
s.ConnectImplementationsToTypesClosing(typeof(ICommandHandler<>));
s.ConnectImplementationsToTypesClosing(typeof(ICommandValidator<>));
s.WithDefaultConventions();
For(typeof(ICommandHandler<>)).DecorateAllWith(typeof(ValidationCommandHandlerDecorator<>));
});
}
}
Now, since I register that decorator for every single ICommandHandler, if I ever have a command that doesn't need a validator and doesn't define one, the ICommandValidator<TCommand> _commandValidator
private field of the ValidationCommandHandlerDecorator<TCommand>
class cannot be found because it of course does not exist and will always throw a structure map error of:
"No default Instance is registered and cannot be automatically determined for type 'ICommandValidator' There is no configuration specified for ICommandValidator"
Is there a way in structure map to define how the ValidationCommandHandlerDecorator
gets constructed so that is uses some type of default validator when one does not exist without having to either take a dependency on the container in the class or having to create an IValidateableCommandHandler<TCommand>
interface to handle commands with validators?
Thank you.
In case anyone comes across this later, the solution I came up with was to add a DefaultCommandValidator class as a Null Object pattern class:
public class DefaultCommandValidator<TCommand> : ICommandValidator<TCommand> where TCommand : CommandBase
{
public IEnumerable<string> Validate(TCommand command)
{
return Enumerable.Empty<string>();
}
}
And then add this line to the structure map registry:
For(typeof(ICommandValidator<>)).Use(typeof(DefaultCommandValidator<>));
I wasn't aware that this structure map syntax will actually use the default instance ONLY if it can't find a concrete implementation of ICommandValidator<TCommand>
. Now, if I don't have a validator, I simply don't add one and the DefaultCommandValidator<TCommand>
instance is used to return an empty/successful validation.