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.
 This post is about how I organize by feature.  Features being my commands and queries.
If you have not familiar with CQRS, it may be worth a look at some of my other posts to get some Context.
This post is about how I organize by feature.  Features being my commands and queries.
If you have not familiar with CQRS, it may be worth a look at some of my other posts to get some Context.
- Thin Controllers with CQRS and MediatR
- Query Objects instead of Repositories
- Mediator Pattern using MediatR and Unity
Layers
What I found interesting was as I moved from thinking about layers to thinking about features and vertical slices, I didn’t immediately organize my code that way. I would still organize my code by what it represented (eg layer). My project structure would look something like this: In the example above, for a Web Api type endpoint for returning data regarding a customer, there are 3 files I would have open:
In the example above, for a Web Api type endpoint for returning data regarding a customer, there are 3 files I would have open:
- Controllers/CustomerController.cs
- Queries/GetCustomer.cs
- ViewModels/CustomerViewModel.cs
- Controllers/CustomersController.cs
- Commands/ChangeCustomerPricingLevelc.s
Why?
I was so used to organizing code by layer, but there was no real reason to. Simply out of habit. One reason was also the ASP.NET Routing convention. I always used routes by naming convention rather than by using the Route attribute. I’m not a particular fan of Attributes, but that’s another discussion. Luckily in NancyFX you define your routes a bit different in the Constructor of your Module (similar to Controller).Organize by Feature
There is nothing stopping us from taking all relevant classes associated to a command or query and adding them to all one file. This provides a really easy way to view all the relevant code where you would need to make change. By organizing by feature, our structure could now look like: