Skip to content

Organize by Feature

Sponsor: Using RabbitMQ or Azure Service Bus in your .NET systems? Well, you could just use their SDKs and roll your own serialization, routing, outbox, retries, and telemetry. I mean, seriously, how hard could it be?

Learn more about Software Architecture & Design.
Join thousands of developers getting weekly updates to increase your understanding of software architecture and design concepts.


Organize by FeatureThis 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.

 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: By Layer 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
For commands, the list is slightly reduced to:
  • 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: byfeature

Single File

For our ChangeCustomerPricing level command, we can now have the our Module (Controller), Command, Handler all within the same file for easy access and modification. My convention has been to add them all to the same namspace.  The namespace being the name of the feature.
Our CustomerModel.cs and all other models that may cut across multiple queries or commands will still be organized by Folder. If we end up adding additional functionality to a command or query, say Validation or Authorization, we can do so in the appropriate feature file.

Tests

One complaint I still have is not being able to have Tests in a very accessible way since they are in a separate test project.  Resharpers “Show Covering Tests”is an easier way to navigate but I’m still looking for something more.

Comments

I’d love to hear how you organize by feature or any other insights.  Please share in the comments below or on twitter.

Related Posts