Let's take some CRUD application for example. I have 4 requests for Create, Read, Update, Delete actually 5 with Get All (I'm building resource-oriented web API)
Is it good to handle them in a single handler like or is something wrong with this approach?:
public class ProductRequestHandler :
IRequestHandler<CreateProductRequest, ProductResult>,
IRequestHandler<GetProductRequest, ProductResult>
IRequestHandler<GetAllProductsRequest, ProductListResult>
IRequestHandler<UpdateProductRequest, ProductResult>
IRequestHandler<DeleteProductRequest, bool>
{
...
}
I'm trying to move away from DDD services that handle similar logic but I don't know if it's worth it.
Also, could someone tell me why shouldn't my Create request return anything if I wanted to apply CQRS? What's the benefit of commands not returning anything? Doing this just for the sake of "responsibility segregation" doesn't convince me. My DDD services returned stuff in my Create methods and my Update methods.
I'm sorry, the question might be trivial for some of you but it's actually pretty confusing topic. And I'd like to get my mind right
TL:DR; If you implement all those interfaces in that single class - are you not just going back to the n-tier architecture days, where the service layer was a class that held all the logic. If you want to do that, I don't see the point in using MediatR.
Longer version
MediatR allows you to break your application up into distinct requests (like microservices) and handle a specific pipeline for each. This gives enormous benefits, both in maintainability and flexibility.
I feel that with your approach you're kinda of breaking those principles thus rendering the underlying framework a tad irrelevant.
Nothing is obviously stopping you from doing that, but to answer your question _is this a good approach_, my gut feeling would be not really. This is just my take - I have no doubt others may feel differently
@no1melman that's something I was thinking. I felt something is wrong with the code and that type of handling isn't much different than having services.
MediatR allows you to break your application up into distinct requests (like microservices) and handle a specific pipeline for each. This gives enormous benefits, both in maintainability and flexibility.
Could you give some real-world example of such benefits based on your experiences?
are you not just going back to the n-tier architecture days
n-tier architecture is still used nowadays in many projects and examples. I actually started my latest project using n-tier architecture but I'm thinking to drop that and re-write it to MediatR because code seems more concise and modular and event-driven.
It would be nice to get some response from @jbogard too
Ditto. Don't combine your handlers, keep them separate, reduce coupling across handlers. For a real example, you can look at my various ContosoUniversity projects under my root profile.
A comment just after this closed.
I will say that it depends. I totally agree with Bogard that, the way you illustrate it in you opening comment is not the way to go.
However, I've just implemented a scenario where I have a command "CreateUserCommand" which needs to know whether the user is already a customer or not. The way we do this is by looking up insurance coverages for the user's danish SSN and if any exist, the user is already a customer.
However, this is quite an expensive process and we do snapshotting and caching of this to improve performance. Furthermore this lookup is done in several places in our API.
So, we have implemented a CustomerCoveragesQuery, to handle this. It goes through the pipeline and is automatically snapshotted (is that a word?) and cached. This is done by our generic Snapshot- and CachingBehaviors.
Now, back to the question. Our CreateUserCommandHandler actually fires off a CustomerCoveragesQuery and reacts on the result but now with fully transparent caching and snapshotting.
Agreed, this gives a coupling between the command and query and could have been solved by a simple service layer, but we wanted to stick with CQRS as much as possible.
Cheers :-)
@SoftInvent so you're injecting IMediator to your handlers and send queries from there, that seems valid when using full CQRS. Thanks for giving an answer based on your experience :)
@lecoque Yes, I've create an abstract CommandHandler
Most helpful comment
Ditto. Don't combine your handlers, keep them separate, reduce coupling across handlers. For a real example, you can look at my various ContosoUniversity projects under my root profile.