Friday, December 23, 2016

MediatR, FluentValidation, and Ninject using Decorators (Pt. 2)

Validate all the Things?

The last post showed how to combine MediatR, FluentValidation, and Ninject to handle the validation of requests handled by MediatR. The drawback in the previous post is that all requests must have a corresponding validator implemented. Here, we'll look at using the null object pattern to bypass validation when a validator isn't present.

Null Object What?

The null object pattern is a way to pass an object which represents nothing, but does not throw a runtime exception when used. This pattern can be used to add default behavior to a process when there is nothing for the process to use.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
    public class ValidatingHandler<TRequest, TResponse> : IRequestHandler<TRequest, TResponse>
        where TRequest : IRequest<TResponse>
    {
        private readonly IRequestHandler<TRequest, TResponse> handler;
        private readonly IValidator<TRequest> validator;

        public ValidatingHandler(IRequestHandler<TRequest, TResponse> handler, IValidator<TRequest> validator)
        {
            this.handler = handler;
            this.validator = validator;
        }

        [DebuggerStepThrough]
        public TResponse Handle(TRequest message)
        {
            var validationResult = validator.Validate(message);

            if (validationResult.IsValid)
                return handler.Handle(message);

            throw new ValidationException(validationResult.Errors);
        }
    }

The handler above is taken from the last post. It accepts a handler and validator for a given request. It validates the request, then either passes the request to the next handler, or throws an exception. Ninject will throw an exception when it cannot find an appropriate validator for the request.


1
2
3
4
    public class NullValidator<TType> : AbstractValidator<TType>
    {
        
    }

Enter a null validator. This validator has no rules. When used, it will return no errors, because there are no rules defined in it. Because it's defined as a generic, it can be used to validate any request. When the handler processes a request, the validation passes by default, and the request is passed down the chain.

The cool thing is there's no extra steps needed. Just add the null validator to the solution. It will be picked up by Ninject in the normal registration process. When Ninject can't find the appropriate validator for a request, it will fall back to the generic implementation.

PS...

That's all there is to adding a class which will provide a default behavior of passing requests that have no validation rules defined. Adding code like this is also a great example of the open-closed principle: It was possible to extend the behavior of the validator without changing the code of the validator. So, there ya go. Default, passing validation using the null object pattern.

As always, the code is on GitHub.

Thursday, December 8, 2016

MediatR, FluentValidation, and Ninject using Decorators

Notebook

I recently had to fiddle with getting Ninject to use decorators for validation with Jimmy Bogard's library, MedatR. Sure, there's tons of blogs out there. There's even some articles on the MediatR and Ninject sites. I had problems getting them to work. So, here's my solution.

CQRS

I've been a fan of the CQRS pattern for some time. For me it's just seems to be a more elegant way to do things. It has some cons: there are usually more classes, and the workflow is not always as clear.

CQRS is Command Query Responsibility Separation (or Segregation). Martin Fowler has a good posting which describes it. It's what it sounds like: separating code logic into commands, queries, and (sometimes) events. One common way of implementing the pattern is to have small objects which are little more than DTOs. These objects are passed to handlers which perform logic based on the contents of the small object.

MediatR

Some time ago, I created a set of classes I used for doing this in projects. These classes were based of Jimmy Bogard's work. Fast-forward a couple years, and I've discovered his library, MediatR. It's as good or better than the set of classes I was using. That was enough for me to make the switch, since I'm a fan reuse when possible.

MediatR is well documented, so I won't repeat all of it. But, for a basic understanding, here's a test showing how a command can be handled by MediatR:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
[Test]
public void ItShouldHandleBasicCommands()
{
    var mediator = GetMediator();

    var command = new Command();
    var response = mediator.Send(command);

    response.Should().NotBeNull();
}

The basic working pieces are the command and the handler. MediatR receives a command, and dispatches it to the appropriate handler. This is what they look like:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
public class Command : IRequest<Response>
{
}

public class CommandHandler : IRequestHandler<Command, Response>
{
    public Response Handle(Command message)
    {
        return new Response();
    }
}

Registering commands and command handlers is pretty easy. Since I've been using Ninject a lot lately, here's an example of registration using Ninject's convention-based registers. It says, find all the handler interfaces, and bind them.

1
2
3
4
kernel.Bind(scan => scan.FromThisAssembly()
    .SelectAllClasses()
    .Where(o => o.IsAssignableFrom(typeof(IRequestHandler<,>)))
    .BindAllInterfaces());

There are a couple other registrations which are important when hooking MediatR and Ninject up. Registering the IMediator interface depends on three calls. The instance factory calls tell MediatR how to resolve single or multiple instances. Then, of course, we register MediatR.

1
2
3
4
5
kernel.Bind<SingleInstanceFactory>()
    .ToMethod(context => (type => context.Kernel.Get(type)));
kernel.Bind<MultiInstanceFactory>()
    .ToMethod(context => (type => context.Kernel.GetAll(type)));
var mediator = kernel.Get<IMediator>();

Validation and Decorators

The decorator pattern is a way of adding behavior to an object without changing the object itself. Decorators can be used to add a number of cross-cutting concerns to another class. One common use is adding input validation. Wrapping a command handler with a decorator makes it possible to validate the command, before the handler processes it. The following command and command handler simply returns a response.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
public class Foo : IRequest<Response>
{
    public string Message { get; set; }
}

public class FooHandler : IRequestHandler<Foo, Response>
{
    public Response Handle(Foo message)
    {
        return new Response();
    }
}

If we wanted to ensure the command, Foo, has a message, we'd want to validate it. FluentValidation is a really handy validation package. Validation requires a validation class, and those classes need to be registered with Ninject.

This is an example of a simple validator. It checks to see if the Message property is empty. If it is, it will return an error.

1
2
3
4
5
6
7
public class FooValidator : AbstractValidator<Foo>
{
    public FooValidator()
    {
        RuleFor(ping => ping.Message).NotEmpty();
    }
}

Registering the validator with Ninject is pretty easy. This line binds all validators in the assembly.

1
2
3
4
kernel.Bind(scan => scan.FromThisAssembly()
    .SelectAllClasses()
    .InheritedFrom(typeof(AbstractValidator<>))
    .BindAllInterfaces());

The next step is to work in a class which will use the validator. The class below comes from Jimmy Bogard's site. It's a pretty common example of how to implement a decorator class which will validate a command, before it is passed to the next handler class.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class ValidatingHandler<TRequest, TResponse> : IRequestHandler<TRequest, TResponse>
    where TRequest : IRequest<TResponse>
{
    private readonly IRequestHandler<TRequest, TResponse> handler;
    private readonly IValidator<TRequest> validator;

    public ValidatingHandler(IRequestHandler<TRequest, TResponse> handler, IValidator<TRequest> validator)
    {
        this.handler = handler;
        this.validator = validator;
    }

    [DebuggerStepThrough]
    public TResponse Handle(TRequest message)
    {
        var validationResult = validator.Validate(message);

        if (validationResult.IsValid)
            return handler.Handle(message);

        throw new ValidationException(validationResult.Errors);
    }
}

The next step is working out how to configure Ninject to create a handler and decorate it. This blog post has a really good description of the process. I've distilled it down for validation below. It says, "Register the handlers. When a validating handler is created, inject a handler. When a handler is requested, return the validating handler." To be honest, I'm not quite sure why the ValidatingHandler has to be registered twice.

When Ninject is asked to create a handler, it first creating a validating handler. It injects the correct command handler and validator into the validating handler.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
kernel.Bind(scan => scan.FromThisAssembly()
    .SelectAllClasses()
    .Where(o => o.IsAssignableFrom(typeof(IRequestHandler<,>)))
    .BindAllInterfaces());

kernel.Bind(scan => scan.FromThisAssembly()
    .SelectAllClasses()
    .InheritedFrom(typeof(IRequestHandler<,>))
    .BindAllInterfaces()
    .Configure(o => o.WhenInjectedInto(typeof(ValidatingHandler<,>))));

kernel.Bind(typeof(IRequestHandler<,>)).To(typeof(ValidatingHandler<,>));

The tests below capture what should happen when the command's message is empty or not.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
[Test]
public void ItShouldProcessCommands()
{
    var mediator = GetMediator();

    var command = new Foo { Message = "valid ping" };
    var response = mediator.Send(command);

    response.Should().NotBeNull();
}

[Test]
public void ItShouldValidateTheCommand()
{
    var mediator = GetMediator();

    var ping = new Foo();
    Action act = () => mediator.Send(ping);

    act.ShouldThrow<ValidationException>();
}

Conclusion

There it is. That's the basics of setting up command validation with Ninject, MediatR, and FluentValidation. It's also a good demonstration of how a decorator can be used to modify behavior without changing existing objects.

As always, there is a sample project on GitHub which has the code from this blog.