Organize by Feature

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

Idempotent Aggregates

Idempotent AggregatesThis blog post will cover creating Idempotent Aggregates and is apart of a series of posts related.

Please take a look any previous posts as they may give more context to the code samples below.


Idempotence

Idempotence is the property of certain operations in mathematics and computer science, that can be applied multiple times without changing the result beyond the initial application.

In my previous post Idempotent Commands, I looked at creating idempotency at the persistence level if you are using an ACID compliance database.

But what happens if you aren’t?  What other options do you have?

Well if you are building a domain model and are creating Aggregates, you could create idempotent aggregates.

Aggregates

If there is enough value and complexity, I will create a domain model with Aggregates that will contain domain behavior and business logic.

This is example is very trivial and I wouldn’t be creating an aggregate for basic CRUD.

However, if we did have a complex domain and aggregate, we can pass in an OperationId to our Aggregate, prior to calling any behavioral methods in order to check if we have already executed that operation.

Handlers

Now in our Command Handler, we can call SetOperation and pass our MessageId from our Envelope<T>.

And as our previous example, here is our NancyFX Module (similar to ASP.NET Controller) which is sending our Command via MediatR.

Concurrency

I have not brought up concurrency as this is something that will be determined based on your data storage solution.

How do you?

How do you handle idempotent commands? I’d love to hear about other implementations or uses.  Comment below or on twitter.


Other Posts

Idempotent Commands

Idempotent CommandsIdempotence is the property of certain operations in mathematics and computer science, that can be applied multiple times without changing the result beyond the initial application.

When you click the “Place Order” button on magical unicorn e-commerce site, you expect your order to be submitted only once.  You also expect that your credit card on on the order you just placed shouldn’t happen more than once.

There are different ways to handle idempotency at various levels of your application.

Persistence

Context is important.  In my context, I’m using a ACID compliant database (MySQL) for storing my current state.

I’m also using Entity Framework as my ORM for handling data/entity state changes.

I can handle idempotency right before I perform my database operation to modifying application state within a database transaction.

Message Identification

In a previous post, Identify Commands & Events, I described creating a Envelope<T> which contains a MessageId that we can use to keep track of messages that have been processed.

In my example, I’m using NancyFX, which uses Modules instead of Controllers.  Even if you are unfamiliar with Nancy, you should be able to understand the gist.

In our route we are going to add a new parameter {MessageId:Guid} which we will then use when creating our Envelope.

Handling

When we make our changes to our database model/entity, we will also attempt to add a new Idempotent object to its mapped table.  First lets create an entity that will contain our unique Id.

With our first pass, lets add a new Idempotent to the database context and check if there is a duplicate key exception.  I’m using MySQL and checking for Error Number 1062 that represents a unique key error.

SaveChangeAsync

The above code is a one way of how handle idempotent commands, however once you implement this more than once you will realize that the next step is to add another method to your Entity Framework Context that will handle the saving of the idempotent entity.

How do you?

How do you handle idempotent commands? I’d love to hear about other implementations or uses.  Comment below or on twitter.


Other Posts