Sponsor: Do you build complex software systems? See how NServiceBus makes it easier to design, build, and manage software systems that use message queues to achieve loose coupling. Get started for free.I’m not a fan of fat controllers. One of the reasons I dislike having my core application logic in controllers is because I like using the web frameworks for what they are good at in my context. My context is usually creating web api’s. For me I use web frameworks as infrastructure that handles
- HTTP routing and endpoints
- Deserialization of input payloads
- Serialization of output payloads
- HTTP Headers and Status Codes
- Web Stuff (eg File Uploads)
Thin ControllersThe way that I remove any of my feature code from my controllers is thru commands and queries. If you are familiar with CQRS, then this will make sense. But I’m not talking about Event Sourcing, Domain Driven Design, or having multiple data stores or any of the overly complex version people think it is. I’m simply talking about splitting up incoming requests into commands and queries.
Starting with CQRS, CQRS is simply the creation of two objects where there was previously only one. The separation occurs based upon whether the methods are a command or a query (the same definition that is used by Meyer in Command and Query Separation, a command is any method that mutates state and a query is any method that returns a value). – Greg YoungThis is pretty straight forward. I’d guess most actually apply CQRS without really knowing it most of the time.
RepositoriesI’m also not a a fan of fat repositories. They generally end up as a giant low cohesive classes full of data access code that is used in one place.
Commands & QueriesI’ve previously posted about using Query Objects instead of Repositories. The same applies for commands. We will create a message (class) that will represent the command/query we want to execute. The message will contain the arguments needed for processing the message. In essence it’s like taking the parameters of a method and turning it into a class. In order to facilitate mapping and handling the execution of command and queries, I use the MediatR.
Simple mediator implementation in .NET In-process messaging with no dependencies. Supports request/response, commands, queries, notifications and events, synchronous and async with intelligent dispatching via C# generic variance.
CommandLet’s take a look at a simple command for changing the pricing level of our customer. Pretty straight forward. It contains the minimum amount of data needed in order for us to perform the given task.
HandlerNow we will create a handler for this command message. Now all that is left is to wire up our command to our web framework.
ControllerIn this example I’m using NancyFX which uses Modules instead of Controllers. This shouldn’t be too hard to translate if you are more familiar with Web Api.
More…Here are some more helpful posts in regards to create commands, queries and MediatR.
- Query Objects instead of Repositories
- Mediator Pattern using MediatR and Unity
- Query Objects with a Mediator