DDD in C# with MongoDB for Persistence — Part 1

Anup Marwadi
HyperTrends
Published in
3 min readJan 22, 2018

--

Hello All, After years of developing n-Tiered Applications as recommended by many “Best-Practice” sites (including Microsoft), we realized that the model was not scalable. We embarked upon a journey into DDD (Domain Driven Design) and seem to have finally figured out a great way to build DDD based applications. Per our estimates, Software Complexity has significantly decreased, reusability has significantly increased, redundant code has been eliminated, and cross-cutting concerns are more formalized.

At some point, I will end up posting actual metrics for many of these items.

If you need an introduction into DDD, please look up YouTube (my preferred go-to search engine for learning new things). If you can, also read up on Uncle Bob’s Clean Code Architecture (there will be a few things you’ll learn), and check out Jimmy Bogard’s NDC Videos.

There are a bunch of really good things you can learn just by watching the above mentioned resources.

I actually want to discuss a few advantages we have seen with MongoDB as the underlying persistence mechanism and demonstrate our approach of building the Domain models. This article will probably be a series by the time I get done demonstrating our approach. Please also note that many of these models will be further enhanced down the line to handle further tenets like CQRS etc. but for now, we’ll keep things very, very simple.

PROBLEM STATEMENT

Given a dollar Amount to charge, a down payment to make, and the total number of payments, and the installment duration in days, the system should generate an installment schedule from the day the order is made.

Let’s say we want to build a Domain Model for building Installments. The down-payment, the installment interval, the total no. of payments are all defined by the person building an installment option. Now that the Installment is created, it can easily be applied to Order checkouts by selecting it as an option.

There we have it. A very simple problem, but good enough to show the various tenets of DDD. What I like about this problem is that it seems quite simple at first, but we can organically grow it to make it better.

A QUICK INITIAL DOMAIN MODEL

If you quickly think about how the installment could be represented, the following data attributes come to mind:

  • Title (for display purposes)
  • A Description (to display the message to the users)
  • Down Payment Amount
  • Total Installments
  • Installment Frequency (say every 30 days, every 15 days etc)

The aggregate root can easily be identified as “Installment”. There isn’t really much complexity here at all. The best way to find an aggregate root is to identify an object-relationship that can be saved in a single transaction boundary. This approach has worked for us and may work for you as well.

However, there are scenarios (as will always be), when this simple mantra may not hold true. At that time, it may be time to go back to the white-board and re-evaluate the domain model and the various relationships.

A quick representation of this model in C# is as follows:

This is a good start, but comes loaded with problems. There’s nothing stopping a consumer from completely destroying this model by changing these properties from anywhere outside the installment. We need to encapsulate the object’s state.

Here’s how I made it a little better:

As you can see, majority of the properties are set to protected set. That means only this class, or any classes that derive from it can set these properties. The Id property is a private setter so that no one else other than this class can change it. It is also initialized to a Guid in the constructor (note that this will change when Mongo DB is introduced, although it doesn’t need to).

I also added an “AggregateRoot” class so that we can identify this installment as an aggregate root.

The benefits are tremendous, once this class is created, no one can modify it from the outside, essentially encapsulating the state. The only valid way to change these items would be to introduce public methods that would allow changing state.

In the next post, we will discuss a few other things that will make this a better domain model. We will also introduce MongoDB to the picture and identify a few different ways of specifying MongoDB mappings to persist this to the database.

--

--

Anup Marwadi
HyperTrends

Tech Entrepreneur. Product Builder. Student for Life. CEO - HyperTrends, TicketBlox