Skip to main content.

Site Map

Site Map

Domain Driven Design

A microservice should be as small as possible and have defined boundaries.

Similar to Bounded Contexts in Domain Driven Design, the goal of is to appropriately size each microservice based on its business domain. You don't want any external references, or as few as possible, so the underlying data model does not become fragmented over multiple services. This causes issues should dependencies be offline or adds to the complexity of assembling a model view over multiple services.

Each microservice we develop is scoped using these techniques. We have a wide range of services being developed that allows our customers to quickly jumpstart a new microservice infrastructure.

IDomainObject and IDomainObject<T>

We have created an advanced, generic-based, polymorphic design to allow the compiler to generate a large portion of source code for us. The IDomainObject interface is the base object used for our object-oriented design. It utilizes a self-referencing interface pattern, that gives us the ability to access typed objects throughout our API layers. This is essential for use with our Business Rule Engine and the customization of logic in our platform.

The following is the definition of a IDomainObject. There is no implementation defined for the interface, as it is used a marker for further implementation.


    public interface IDomainObject
    {
    }

    public interface IDomainObject<T> : IDomainObject
    {
    }

For each repository-driven API service exposed, there is an underlying entity that implements the IDomainObject interface. Different storage providers may enforce additional requirements on each Domain Object. For instance, the AzureDataTables storage provider interface enforces that each domain object must use a PartitionKey and RowKey to define its primary key.

Data Transfer Object (DTO)

A data transfer object is an object that is used to hold data when moved between processes. They are typically just a plain old CLR object (POCO) and should not contain any logic. It is simply a container to move pieces of data around that can be easily serializable.

Regardless if you are using a relational or a document-based storage engine, they all have the concept of being able to identify a piece of data. This is usually done with the notion of Primary Keys. Some providers can use only one key, while others can use multiple, or both. Our first challenge was to expose this concept with a DTO as simply as possible.

Since storage providers can also use different data types, the choice was made to expose this concept as a string. We can serialize any data type to a string and when combined with a delimiter, we can additionally support multiple values. We have defined this concept as the StorageKey.


    public interface IDataTransferObject
    {
        string StorageKey { get; set; }
    }

For each Domain Object that is backed by persistent storage, it can expose one or more DTOs via API services. All the primary keys for the Domain Object are serialized to the single StorageKey property.