I still remember good old days of repositories. But repositories used to grow ugly with time. Then CQRS got mainstream. They were nice, they were a breath of fresh air. But recently I've been asking myself again and again why don't I keep the logic right in a Controller's Action method (especially in Web Api where action is some kind of command/query handler in itself).
Previously I had a clear answer for that: I do it for testing as it's hard to test Controller with all those unmockable singletons and overall ugly ASP.NET infrastructure. But times have changed and ASP.NET infrastructure classes are much more unit tests friendly nowadays (especially in ASP.NET Core).
Here's a typical WebApi call: command is added and SignalR clients are notified about it:
public void AddClient(string clientName)
{
using (var dataContext = new DataContext())
{
var client = new Client() { Name = clientName };
dataContext.Clients.Add(client);
dataContext.SaveChanges();
GlobalHost.ConnectionManager.GetHubContext<ClientsHub>().ClientWasAdded(client);
}
}
I can easily unit test/mock it. More over, thanks to OWIN I can setup local WebApi and SignalR servers and make an integration test (and pretty fast by the way).
Recently I felt less and less motivation to create cumbersome Commands/Queries handlers and I tend to keep code in Web Api actions. I make an exception only if logic is repeated or it's really complicated and I want to isolate it. But I'm not sure if I'm doing the right thing here.
What is the most reasonable approach for managing logic in a typical modern ASP.NET application? When is it reasonable to move your code to Commands and Queries handlers? Are there any better patterns?
Update. I found this article about DDD-lite approach. So it seems like my approach of moving complicated parts of code to commands/queries handlers could be called CQRS-lite.