After some discussion around my last post, Preventing Performance Problems with Entity Framework and Unit of Work, I wanted to illustrate how one might organize code in a way that eases some common performance pains in larger enterprise applications.

This approach is geared more towards the anemic domain model pattern, but it is also essential when dealing with rich domain models.

If we are building an ordering system, we might have an OrderService that is responsible for applying all business logic related to saving an order, and an OrderLineService responsible for logic associated with updating a line item.

The desktop version of our application allows updating an order as a whole, including line items, so we inject the OrderLineService into our OrderService to update each line on the order.

The mobile application allows a user to update the lines individually to account for the small screen size. We can inject our OrderLineService into our OrderLineController.

Here is what our controllers might look like:

OrderController.cs

OrderLineController.cs

And our OrderService and OrderLineService might look like:

OrderService.cs

OrderLineService.cs

The implementation of the OrderLineService allows for calls from both the OrderService when saving an entire order, and the OrderLineService when saving a single line.

The problem with this implementation is that a query will be executed for each line item. This is your classic N+1 problem. To fix this, we could add another method to the OrderLineService to allow passing in the OrderLine object. This will allow querying the OrderRepository for the Order and OrderLine objects, reducing a round trip to the database.

Another problem with this approach is that, in the situation where an entire order is being saved, _uow.SaveChanges() is called N+1 times. In terms of performance, this quickly gets expensive.

You could get around this problem by overloading the UpdateOrderLine to take in an OrderLine model and skip the unit of work call. But this tends to muddy-up the service; dealing with scoping of queries / the unit of work seems like a separate concern and can be broken out into a separate class.

As a fan of the CQRS pattern, I tend to call these new classes commands for anything that is making changes to the domain (create, update, delete), and queries for anything that is requesting data (reads). In this scenario, we could have two commands, UpdateOrderCommand and UpdateOrderLineCommand. These services would serve as entry points into your domain, and their entire purpose is to manage the steps needed to execute the requested changes (updating an order and order line). The command is injected into the controllers, and the domain service is injected into the command.

In this case, our controller, command, and service for updating an order could look like:

The most notable change in the above code sample is that we no longer pass just the model to the OrderLineService , we pass the model and the OrderLine object that we retrieved from the database when loading the entire order in the command service.

With this approach, we remove the loading and saving of entities from the domain service, allowing them to focus purely on executing domain logic. This keeps the services more narrowly focused and allows the flexibility to load data in the most efficient manner. As shown in this example, when updating an entire order, we load the order and all of its lines at once as opposed to loading the lines inside of a loop. When updating a single line, we can load just that line. And finally, we can now reuse domain services in other domain services without persistence constraints.