A model .NET web service based on Domain Driven Design Part 8: the concrete Service

We’ll continue where we left off in the previous post. It’s time to implement the first concrete service in the skeleton application: the CustomerService.

Open the project we’ve been working on in this series. Locate the ApplicationServices layer and add a new folder called Implementations. Add a new class called CustomerService which implements the ICustomerService interface we inserted in the previous post. The initial skeleton will look like this:

public class CustomerService : ICustomerService
{
	public GetCustomerResponse GetCustomer(GetCustomerRequest getCustomerRequest)
	{
		throw new NotImplementedException();
	}

	public GetCustomersResponse GetAllCustomers()
	{
		throw new NotImplementedException();
	}

	public InsertCustomerResponse InsertCustomer(InsertCustomerRequest insertCustomerRequest)
	{
		throw new NotImplementedException();
	}

	public UpdateCustomerResponse UpdateCustomer(UpdateCustomerRequest updateCustomerRequest)
	{
		throw new NotImplementedException();
	}

	public DeleteCustomerResponse DeleteCustomer(DeleteCustomerRequest deleteCustomerRequest)
	{
		throw new NotImplementedException();
	}
}

We know that the service will need some repository to retrieve the requested records. Which repository is it? The abstract one of course: ICustomerRepository. It represents all operations that the consumer is allowed to do in the customer repository. The service layer doesn’t care about the exact implementation of this interface.

We’ll also need a reference to the unit of work which will maintain and persist the changes we make. Again, we’ll take the abstract IUnitOfWork object.

These abstractions must be injected into the customer service class through its constructor. You can read about constructor injection and the other types of dependency injection here.

Add the following backing fields and the constructor to CustomerService.cs:

private readonly ICustomerRepository _customerRepository;
private readonly IUnitOfWork _unitOfWork;

public CustomerService(ICustomerRepository customerRepository, IUnitOfWork unitOfWork)
{
	if (customerRepository == null) throw new ArgumentNullException("Customer repo");
	if (unitOfWork == null) throw new ArgumentNullException("Unit of work");
	_customerRepository = customerRepository;
	_unitOfWork = unitOfWork;
}

Let’s implement the GetCustomer method first:

public GetCustomerResponse GetCustomer(GetCustomerRequest getCustomerRequest)
{
	GetCustomerResponse getCustomerResponse = new GetCustomerResponse();
	Customer customer = null;
	try
	{
		customer = _customerRepository.FindBy(getCustomerRequest.Id);
		if (customer == null)
		{
			getCustomerResponse.Exception = GetStandardCustomerNotFoundException();
		}
                else
		{
			getCustomerResponse.Customer = customer.ConvertToViewModel();
		}
	}
	catch (Exception ex)
	{
		getCustomerResponse.Exception = ex;
	}
	return getCustomerResponse;
}

…where GetStandardCustomerNotFoundException() looks like this:

private ResourceNotFoundException GetStandardCustomerNotFoundException()
{
	return new ResourceNotFoundException("The requested customer was not found.");
}

…where ResourceNotFoundException looks like the following:

public class ResourceNotFoundException : Exception
{
	public ResourceNotFoundException(string message)
		: base(message)
	{}

	public ResourceNotFoundException()
		: base("The requested resource was not found.")
	{}
}

There’s nothing too complicated in the GetCustomer method I hope. Note that we use the extension method ConvertToViewModel() we implemented in the previous post to return a customer view model. We call upon the FindBy method of the repository to locate the resource and save any exception thrown along the way.

GetAllCustomers is equally simple:

public GetCustomersResponse GetAllCustomers()
{
	GetCustomersResponse getCustomersResponse = new GetCustomersResponse();
	IEnumerable<Customer> allCustomers = null;

	try
	{
		allCustomers = _customerRepository.FindAll();
                getCustomersResponse.Customers = allCustomers.ConvertToViewModels();
	}
	catch (Exception ex)
	{
		getCustomersResponse.Exception = ex;
	}	
	return getCustomersResponse;
}

In the InsertCustomer method we create a new Customer domain object, validate it, call the repository to insert the object and finally call the unit of work to commit the changes:

public InsertCustomerResponse InsertCustomer(InsertCustomerRequest insertCustomerRequest)
{
	Customer newCustomer = AssignAvailablePropertiesToDomain(insertCustomerRequest.CustomerProperties);
	ThrowExceptionIfCustomerIsInvalid(newCustomer);
	try
	{
		_customerRepository.Insert(newCustomer);				
		_unitOfWork.Commit();
		return new InsertCustomerResponse();
	}
	catch (Exception ex)
	{
		return new InsertCustomerResponse() { Exception = ex };
	}
}

…where AssignAvailablePropertiesToDomain looks like this:

private Customer AssignAvailablePropertiesToDomain(CustomerPropertiesViewModel customerProperties)
{
	Customer customer = new Customer();
	customer.Name = customerProperties.Name;
	Address address = new Address();
	address.AddressLine1 = customerProperties.AddressLine1;
	address.AddressLine2 = customerProperties.AddressLine2;
	address.City = customerProperties.City;
	address.PostalCode = customerProperties.PostalCode;
	customer.CustomerAddress = address;
	return customer;
}

So we simply dress up a new Customer domain object based on the properties of the incoming CustomerPropertiesViewModel object. In the ThrowExceptionIfCustomerIsInvalid method we validate the Customer domain:

private void ThrowExceptionIfCustomerIsInvalid(Customer newCustomer)
{
	IEnumerable<BusinessRule> brokenRules = newCustomer.GetBrokenRules();
	if (brokenRules.Count() > 0)
	{
		StringBuilder brokenRulesBuilder = new StringBuilder();
		brokenRulesBuilder.AppendLine("There were problems saving the LoadtestPortalCustomer object:");
		foreach (BusinessRule businessRule in brokenRules)
		{
			brokenRulesBuilder.AppendLine(businessRule.RuleDescription);
		}

		throw new Exception(brokenRulesBuilder.ToString());
	}
}

Revisit the post on EntityBase and the Domain layer if you’ve forgotten what the BusinessRule object and the GetBrokenRules() method are about.

In the UpdateCustomer method we first check if the requested Customer object exists. Then we change its properties based on the incoming UpdateCustomerRequest object. The process after that is the same as in the case of InsertCustomer:

public UpdateCustomerResponse UpdateCustomer(UpdateCustomerRequest updateCustomerRequest)
{
	try
	{
		Customer existingCustomer = _customerRepository.FindBy(updateCustomerRequest.Id);
		if (existingCustomer != null)
		{
			Customer assignableProperties = AssignAvailablePropertiesToDomain(updateCustomerRequest.CustomerProperties);
			existingCustomer.CustomerAddress = assignableProperties.CustomerAddress;
			existingCustomer.Name = assignableProperties.Name;
			ThrowExceptionIfCustomerIsInvalid(existingCustomer);
			_customerRepository.Update(existingCustomer);
			_unitOfWork.Commit();
			return new UpdateCustomerResponse();
		}
		else
		{
			return new UpdateCustomerResponse() { Exception = GetStandardCustomerNotFoundException() };
		}
	}
	catch (Exception ex)
	{
		return new UpdateCustomerResponse() { Exception = ex };
	}
}

In the DeleteCustomer method we again first retrieve the object to see if it exists:

public DeleteCustomerResponse DeleteCustomer(DeleteCustomerRequest deleteCustomerRequest)
{
	try
	{
		Customer customer = _customerRepository.FindBy(deleteCustomerRequest.Id);
		if (customer != null)
		{
			_customerRepository.Delete(customer);
			_unitOfWork.Commit();
			return new DeleteCustomerResponse();
		}
		else
		{
			return new DeleteCustomerResponse() { Exception = GetStandardCustomerNotFoundException() };
		}
	}
	catch (Exception ex)
	{
		return new DeleteCustomerResponse() { Exception = ex };
	}
}

That should be it really, this is the implementation of the CustomerService class.

In the next post we’ll start building the ultimate consumer of the application: the web layer which in this case will be a Web API web service. However, it could equally be a Console app, a WPF desktop app, a Silverlight app or an MVC web app, etc. It’s up to you what type of interface you build upon the backend skeleton.

View the list of posts on Architecture and Patterns here.

A model .NET web service based on Domain Driven Design Part 6: the concrete Repository continued

Introduction

In the previous post we laid the foundation for the concrete domain-specific repositories. We implemented the IUnitOfWork and IUnitOfWorkRepository interfaces and created an abstract Repository class. It’s time to see how we can implement the Customer repository. We’ll continue where we left off in the previous post.

The concrete Customer repository

Add a new folder called Repositories in the Repository.Memory data access layer. Add a new class called CustomerRepository with the following stub:

public class CustomerRepository : Repository<Customer, int, DatabaseCustomer>, ICustomerRepository
{
         public CustomerRepository(IUnitOfWork unitOfWork, IObjectContextFactory objectContextFactory) :  base(unitOfWork, objectContextFactory)
	{}

	public override Customer FindBy(int id)
	{
		throw new NotImplementedException();
	}

	public override DatabaseCustomer ConvertToDatabaseType(Customer domainType)
	{
		throw new NotImplementedException();
	}

	public IEnumerable<Customer> FindAll()
	{
		throw new NotImplementedException();
	}
}

You’ll need to add a reference to the Domain layer for this to compile.

We derive from the abstract Repository class and declare that the object is represented by the Customer class in the domain layer and by the DatabaseCustomer in the data storage layer and has an id type int. We inherit the FindBy, the ConvertToDatabaseType and the FindAll methods. FindAll() is coming indirectly from the IReadOnlyRepository interface which is implemented by IRepository which in turn is implemented by ICustomerRepository. And where are the three methods of IRepository? Remember, that the Update, Insert and Delete methods have already been implemented in the Repository class so we don’t need to worry about them. Any time we create a new domain-specific repository, those methods have been taken care of.

Let’s implement the methods one by one. In the FindBy(int id) method we’ll need to consult the DatabaseCustomers collection first and get the DatabaseCustomer object with the incoming id. Then we’ll populate the Customer domain object from its database representation. The DatabaseCustomers collection can be retrieved using the IObjectContextFactory dependency of the base class. However, its backing field is private, so let’s add the following read-only property to Repository.cs:

public IObjectContextFactory ObjectContextFactory
{
	get
	{
		return _objectContextFactory;
	}
}

The FindBy(int id) method can be implemented as follows:

public override Customer FindBy(int id)
{
	DatabaseCustomer databaseCustomer = (from dc in ObjectContextFactory.Create().DatabaseCustomers
										 where dc.Id == id
										 select dc).FirstOrDefault();
	Customer customer = new Customer()
	{
		Id = databaseCustomer.Id
		,Name = databaseCustomer.CustomerName
		,CustomerAddress = new Address()
		{
			AddressLine1 = databaseCustomer.Address
			,AddressLine2 = string.Empty
			,City = databaseCustomer.City
			,PostalCode = "N/A"
		}
	};
	return customer;
}

So we populate the Customer object based on the properties of the DatabaseCustomer object. We don’t store the postal code or address line 2 in the DB so they are not populated. In a real life scenario we’d probably need to rectify this by extending the DatabaseCustomer table, but for now we don’t care. This example shows again the advantage of having complete freedom over the database and domain representations of a domain. You have the freedom of populating the domain object from its underlying database representation. You can even consult other database objects if needed as the domain object properties may be dispersed across 2-3 or even more database tables. The domain object won’t be concerned with such details. The domain and the database are completely detached so you don’t have to worry about changing either the DB or the domain representation.

Let’s factor out the population process to a separate method as it will be needed later:

private Customer ConvertToDomain(DatabaseCustomer databaseCustomer)
{
	Customer customer = new Customer()
	{
		Id = databaseCustomer.Id
		,Name = databaseCustomer.CustomerName
		,CustomerAddress = new Address()
		{
			AddressLine1 = databaseCustomer.Address
			,AddressLine2 = string.Empty
			,City = databaseCustomer.City
			,PostalCode = "N/A"
		}
	};
	return customer;
}

The update version of FindBy(int id) looks as follows:

public override Customer FindBy(int id)
{
	DatabaseCustomer databaseCustomer = (from dc in ObjectContextFactory.Create().DatabaseCustomers
										 where dc.Id == id
										 select dc).FirstOrDefault();
	if (databaseCustomer != null)
	{
		return ConvertToDomain(databaseCustomer);
	}
	return null;
}

The ConvertToDatabaseType(Customer domainType) method will be used when inserting and modifying domain objects:

public override DatabaseCustomer ConvertToDatabaseType(Customer domainType)
{
	return new DatabaseCustomer()
	{
		Address = domainType.CustomerAddress.AddressLine1
		,City = domainType.CustomerAddress.City
		,Country = "N/A"
		,CustomerName = domainType.Name
		,Id = domainType.Id
		,Telephone = "N/A"
	};
}

Nothing fancy here I suppose.

Finally FindAll simply retrieves all customers from the database and converts each to a domain type:

public IEnumerable<Customer> FindAll()
{
	List<Customer> allCustomers = new List<Customer>();
	List<DatabaseCustomer> allDatabaseCustomers = (from dc in ObjectContextFactory.Create().DatabaseCustomers
						   select dc).ToList();
	foreach (DatabaseCustomer dc in allDatabaseCustomers)
	{
		allCustomers.Add(ConvertToDomain(dc));
	}
	return allCustomers;
}

That’s it, there’s at present nothing more to add the CustomerRepository class. If you add any specialised queries in the ICustomerRepository interface they will need to be implemented here.

I’ll finish this post with a couple of remarks on EntityFramework.

Entity Framework

There is a way to implement the Unit of Work pattern in conjunction with the EntityFramework in a different, more simplified way. The database type is completely omitted from the structure leading to the following Repository abstract class declaration:

public abstract class Repository<DomainType, IdType> : IUnitOfWorkRepository where DomainType : IAggregateRoot

So there’s no trace of how the domain is represented in the database. There is a way in the EF designer to map the columns of a table to the properties of an object. You can specify the namespace of the objects created by EF – the .edmx file – like this:

1. Remove the code generation tool from the edmx file properties:

Remove EF code generation tool

2. Change the namespace of the project by right-clicking anywhere on the EF diagram and selecting Properties:

Change namespace in entity framework

Change that value to the namespace of your domain objects.

3. If the ID of a domain must be auto-generated by the database then you’ll need to set the StoreGeneratedPattern to Identity on that field:

EF identity generation

You can fine-tune the mapping by opening the .edmx file in a text editor. It is standard XML so you can edit it as long as you know what you are doing.

This way we don’t need to declare the domain type and the database type, we can work with only one type because it will be common to EF and the domain model. It is reasonable to follow down this path as it simplifies certain things, e.g. you don’t need the conversions between DB and domain types. However, there are some things to keep in mind I believe.

We inherently couple the domain object to its database counterpart. It may work with simple domain objects, but not with more complex objects where the database representation can be spread out in different tables. We may even face a different scenario: say we made a design mistake in the database structuring phase and built a table that represents more than one domain object. We may not have the possibility of rebuilding that table as it contains millions of rows and is deployed in a production environment. How do we then map 2 or more domain objects to the same database table in the EF designer? It won’t work, at least I don’t know any way how this can be solved. Also, mapping stored procedures to domain objects or domain object rules can be problematic. What’s more, you’ll need to mark those properties of your domains virtual where you want to allow lazy loading by the ORM framework like this:

public class Book
{
    public int Id { get; set; }
    public virtual Title Title { get; set; }
}

I think this breaks the persistence ignorance (PI) feature of proper POCO classes. We’re modifying the domain to give way for a persistence technology.

However, you may be OK with these limitations. Your philosophy may well differ from my rigid PI and POCO approach. It is certainly desirable that the database tables and domains are as close as possible, but you don’t always have this luxury with large legacy databases. If you start off with a completely empty database with no tables then EF and the code-first approach – where the data tables will be created for you based on your self-written object context implementation – can simplify the repository development process. However, keep in mind that database tables are a lot more rigid and resistant to change than your loosely coupled and layered code. Once the database has been put into production and you want to change the structure of a domain object you may run into difficulties as the corresponding database table may not be modified that easily.

In the next post we’ll discuss the application services layer.

View the list of posts on Architecture and Patterns here.

A model .NET web service based on Domain Driven Design Part 5: the concrete Repository

Introduction

In the previous post we laid the foundation for our repository layer. It’s now time to see how those elements can be implemented. The implemented data access layer will be a simple in-memory data storage solution. I could have selected something more technical, like EntityFramework but giving a detailed account on a data storage mechanism is not the target of these series. It would probably only sidetrack us too much. The things we take up in this post should suffice for you to implement an EF-based concrete repository.

This is quite a large topic and it’s easy to get lost so this post will be devoted to laying the foundation of domain-specific repositories. In the next post we’ll implement the Customer domain repository.

The Customer repository

We need to expose the operations that the consumer of the code is allowed to perform on the Customer object. Recall from the previous post that we have 2 interfaces: one for read-only entities and another for the ones where we allow all CRUD operations. We want to be able to insert, select, modify and delete Customer objects. The domain-specific repository interfaces must be declared in the Domain layer.

This point is important to keep in mind: it is only the data access abstraction we define in the Domain layer. It is up to the implementing data access mechanism to hide the implementation details. We do this in order to keep the Domain objects completely free of persistence logic so that they remain persistence-ignorant. You can persist the domains in the repository layer the way you want, it doesn’t matter, as long as those details do not bubble up to the other layers in any way, shape or form. Once you start referencing e.g. the DB object context in the web layer you have committed to use EntityFramework and a switch to another technology will be all the more difficult.

Insert the following interface in the Domain/Customer folder:

public interface ICustomerRepository : IRepository<Customer, int>
{
}

Right now it’s an empty interface as we don’t want to declare any new data access capability over and above the methods already defined in the IRepository interface. Recall that we included the FindAll() method in the IReadOnlyRepository interface which allows us to retrieve all entities from the data store. This may be dangerous to perform on an entity where we have millions of rows in the database. Therefore you may want to remove that method from the interface. However, if we only have a few customers then it may be OK and you could have the following customer repository:

public interface ICustomerRepository : IRepository<Customer, int>
{
	IEnumerable<Customer> FindAll();
}

The Repository layer

Insert a new C# class library called DDDSkeletonNET.Portal.Repository.Memory. Add a reference to the Infrastructure layer as we’ll need access to the abstractions defined there. We’ll first need to implement the Unit of Work. Add the following stub implementation to the Repository layer:

public class InMemoryUnitOfWork : IUnitOfWork
{
	public void RegisterUpdate(IAggregateRoot aggregateRoot, IUnitOfWorkRepository repository)
	{}

	public void RegisterInsertion(IAggregateRoot aggregateRoot, IUnitOfWorkRepository repository)
	{}

	public void RegisterDeletion(IAggregateRoot aggregateRoot, IUnitOfWorkRepository repository)
	{}

	public void Commit()
	{}
}

Let’s fill this in. As we don’t have any built-in solution to track the changes to our entities we’ll have to store the changes ourselves in in-memory collections. Add the following private fields to the class:

private Dictionary<IAggregateRoot, IUnitOfWorkRepository> _insertedAggregates;
private Dictionary<IAggregateRoot, IUnitOfWorkRepository> _updatedAggregates;
private Dictionary<IAggregateRoot, IUnitOfWorkRepository> _deletedAggregates;

We keep track of the changes in these dictionaries. Recall the function of the unit of repository: it will perform the actual data persistence.

We’ll initialise these objects in the unit of work constructor:

public InMemoryUnitOfWork()
{
	_insertedAggregates = new Dictionary<IAggregateRoot, IUnitOfWorkRepository>();
	_updatedAggregates = new Dictionary<IAggregateRoot, IUnitOfWorkRepository>();
	_deletedAggregates = new Dictionary<IAggregateRoot, IUnitOfWorkRepository>();
}

Next we implement the registration methods which in practice only means that we’re filling up these dictionaries:

public void RegisterUpdate(IAggregateRoot aggregateRoot, IUnitOfWorkRepository repository)
{
	if (!_updatedAggregates.ContainsKey(aggregateRoot))
	{
		_updatedAggregates.Add(aggregateRoot, repository);
	}
}

public void RegisterInsertion(IAggregateRoot aggregateRoot, IUnitOfWorkRepository repository)
{
	if (!_insertedAggregates.ContainsKey(aggregateRoot))
	{
		_insertedAggregates.Add(aggregateRoot, repository);
	}
}

public void RegisterDeletion(IAggregateRoot aggregateRoot, IUnitOfWorkRepository repository)
{
	if (!_deletedAggregates.ContainsKey(aggregateRoot))
	{
		_deletedAggregates.Add(aggregateRoot, repository);
	}
}

We only want to add those changes that haven’t been added before hence the ContainsKey guard clause.

In the commit method we ask the unit of work repository to persist those changes:

public void Commit()
{
	foreach (IAggregateRoot aggregateRoot in _insertedAggregates.Keys)
	{
		_insertedAggregates[aggregateRoot].PersistInsertion(aggregateRoot);
	}

	foreach (IAggregateRoot aggregateRoot in _updatedAggregates.Keys)
	{
		_updatedAggregates[aggregateRoot].PersistUpdate(aggregateRoot);
	}

	foreach (IAggregateRoot aggregateRoot in _deletedAggregates.Keys)
	{
		_deletedAggregates[aggregateRoot].PersistDeletion(aggregateRoot);
	}
}

At present we don’t care about transactions and rollbacks as a fully optimised implementation is not the main goal here. We can however extend the Commit method to accommodate transactions:

public void Commit()
{
    using (TransactionScope scope = new TransactionScope())
    {
         //foreach loops...
         scope.Complete();
    }
}

You’ll need to import the System.Transactions library for this to work.

So what does a unit of work repository implementation look like? We’ll define it as a base abstract class that each concrete repository must derive from. We’ll build up an example step by step. Add the following stub to the Repository layer:

public abstract class Repository<DomainType, IdType, DatabaseType> : IUnitOfWorkRepository where DomainType :  IAggregateRoot
{
	private readonly IUnitOfWork _unitOfWork;

	public Repository(IUnitOfWork unitOfWork)
	{
		if (unitOfWork == null) throw new ArgumentNullException("Unit of work");
		_unitOfWork = unitOfWork;
	}

	public void PersistInsertion(IAggregateRoot aggregateRoot)
	{
		
	}

	public void PersistUpdate(IAggregateRoot aggregateRoot)
	{
			
	}

	public void PersistDeletion(IAggregateRoot aggregateRoot)
	{
		
	}
}

There’s not much functionality in here yet, but it’s an important first step. The Repository abstract class implements IUnitOfWorkRepository so it will be the persistence workhorse of the data storage. It has three type parameters: DomainType, IdType and DatabaseType.

TypeId probably sounds familiar by now so I won’t dive into more details now. Then we distinguish between the domain type and the database type. The domain type will be the type of the domain class such as the Customer domain we’ve created. The database type will be the database representation of the same domain.

Why might we need a database type? It is not guaranteed that a domain object will have the same structure in the storage as in the domain layer. In the domain layer you have the freedom of adding, modifying and removing properties, rules etc. You may not have the same freedom in a relational database. If a data table is used by stored procedures and user-defined functions then you cannot just remove columns at will without breaking a lot of other DB logic. With the advent of NoSql databases, such as MongoDb or RavenDb, which allow a very loose and flexible data structure this requirement may change but at the time of writing this post relational databases are still the first choice for data storage. Usually as soon as a database is put into production and LIVE data starts to fill up the data tables with potentially hundreds of thousands of rows every day then the data table structure becomes a lot more rigid than your domain classes. Hence it can be a good idea to isolate the “domain” and “database” representations of a domain object. It is of course only the concrete repository layer that should know how a domain object is represented in the data storage.

Before we continue with the Repository class let’s simulate the database representation of the Customer class. This can be likened to the objects that the EF or Linq to SQL automation tools generate for you. Insert a new folder called Database in the Repository.Memory layer. Insert the following class into it:

public class DatabaseCustomer
{
	public int Id { get; set; }
	public string CustomerName { get; set; }
	public string Address { get; set; }
	public string Country { get; set; }
	public string City { get; set; }
	public string Telephone { get; set; }
}

This example shows an advantage with having separate domain and database representations. Recall that the Customer domain has an Address value object. In this example we imagine that there’s no separate Address table, we didn’t think of that when we designed the original database. As the database has been in use for some time it’s probably even too late to create a separate Address table so that we don’t interrupt the LIVE system.

However, we don’t care because we’ve allowed for this possibility by the type parameters. We’re free to construct and convert between domain and database objects in the concrete repository layer.

The next object we’ll need in the database is an imitation of the DB object context in EF and Linq to SQL. I realise that I may be talking too much about these specific ORM technologies but it probably suits the vast majority of data-driven .NET projects out there. Insert the following class into the Database folder:

public class InMemoryDatabaseObjectContext
{
	//simulation of database collections
	public List<DatabaseCustomer> DatabaseCustomers { get; set; }

	public InMemoryDatabaseObjectContext()
	{
		InitialiseDatabaseCustomers();
	}

	public void AddEntity<T>(T databaseEntity)
	{
		if (databaseEntity is DatabaseCustomer)
		{
                        DatabaseCustomer databaseCustomer = databaseEntity as DatabaseCustomer;
			databaseCustomer.Id = DatabaseCustomers.Count + 1;
			DatabaseCustomers.Add(databaseEntity as DatabaseCustomer);
		}
	}

	public void UpdateEntity<T>(T databaseEntity)
	{
		if (databaseEntity is DatabaseCustomer)
		{
			DatabaseCustomer dbCustomer = databaseEntity as DatabaseCustomer;
			DatabaseCustomer dbCustomerToBeUpdated = (from c in DatabaseCustomers where c.Id == dbCustomer.Id select c).FirstOrDefault();
			dbCustomerToBeUpdated.Address = dbCustomer.Address;
			dbCustomerToBeUpdated.City = dbCustomer.City;
			dbCustomerToBeUpdated.Country = dbCustomer.Country;
			dbCustomerToBeUpdated.CustomerName = dbCustomer.CustomerName;
			dbCustomerToBeUpdated.Telephone = dbCustomer.Telephone;
		}
	}

	public void DeleteEntity<T>(T databaseEntity)
	{
		if (databaseEntity is DatabaseCustomer)
		{
			DatabaseCustomer dbCustomer = databaseEntity as DatabaseCustomer;
			DatabaseCustomer dbCustomerToBeDeleted = (from c in DatabaseCustomers where c.Id == dbCustomer.Id select c).FirstOrDefault();
			DatabaseCustomers.Remove(dbCustomerToBeDeleted);
		}
	}

	private void InitialiseDatabaseCustomers()
	{
		DatabaseCustomers = new List<DatabaseCustomer>();
		DatabaseCustomers.Add(new DatabaseCustomer(){Address = "Main street", City = "Birmingham", Country = "UK", CustomerName ="GreatCustomer", Id = 1, Telephone = "N/A"});
		DatabaseCustomers.Add(new DatabaseCustomer() { Address = "Strandvägen", City = "Stockholm", Country = "Sweden", CustomerName = "BadCustomer", Id = 2, Telephone = "123345456" });
		DatabaseCustomers.Add(new DatabaseCustomer() { Address = "Kis utca", City = "Budapest", Country = "Hungary", CustomerName = "FavouriteCustomer", Id = 3, Telephone = "987654312" });
	}
}

First we have a collection of DB customer objects. In the constructor we initialise the collection values so that we don’t start with an empty one. Then we add insertion, update and delete methods for database type T to make it generic. These are somewhat analogous to the InsertOnSubmit, SubmitChanges and the DeleteOnSubmit methods from the Linq to SQL object context. The implementation itself is not too clever of course as we need to check the type but it’s OK for now. Perfection is not the goal in this part of the code, the automation tools will prepare a lot more professional code for you from the database. In the AddEntity we assign an ID based on the number of elements in the database. This is a simulation of the ID auto-assign feature of relational databases.

We’ll need access to this InMemoryDatabaseObjectContext in the repository layer. In a real system this object will be used intensively therefore access to it should be regulated. Creating a new object context for every single DB operation is not too clever so we’ll hide the access behind a thread-safe lazy singleton class. If you don’t know what these term mean, check out my post on the singleton design pattern. I won’t repeat the stuff that’s written there.

Insert the following abstract factory interface in the Database folder:

public interface IObjectContextFactory
{
	InMemoryDatabaseObjectContext Create();
}

The interface will be implemented by the following class:

public class LazySingletonObjectContextFactory : IObjectContextFactory
{
	public InMemoryDatabaseObjectContext Create()
	{
		return InMemoryDatabaseObjectContext.Instance;
	}
}

The InMemoryDatabaseObjectContext object does not have any Instance property yet, so add the following code to it:

public static InMemoryDatabaseObjectContext Instance
{
	get
	{
		return Nested.instance;
	}
}

private class Nested
{
	static Nested()
	{
	}
	internal static readonly InMemoryDatabaseObjectContext instance = new InMemoryDatabaseObjectContext();
}

If you don’t understand what this code does then make sure you read through the post on the singleton pattern.

We’ll need a reference to the abstract factory in the Repository object, so modify the private field declarations and the constructor as follows:

private readonly IUnitOfWork _unitOfWork;
private readonly IObjectContextFactory _objectContextFactory;

public Repository(IUnitOfWork unitOfWork, IObjectContextFactory objectContextFactory)
{
	if (unitOfWork == null) throw new ArgumentNullException("Unit of work");
	if (objectContextFactory == null) throw new ArgumentNullException("Object context factory");
	_unitOfWork = unitOfWork;
	_objectContextFactory = objectContextFactory;
}

At this point it’s also clear that we’ll need to be able to convert a domain type to a database type. This is best implemented in the concrete repository classes so it’s enough to add an abstract method in the Repository class:

public abstract DatabaseType ConvertToDatabaseType(DomainType domainType);

We can implement the Persist methods as follows:

public void PersistInsertion(IAggregateRoot aggregateRoot)
{
	DatabaseType databaseType = RetrieveDatabaseTypeFrom(aggregateRoot);
	_objectContextFactory.Create().AddEntity<DatabaseType>(databaseType);
}

public void PersistUpdate(IAggregateRoot aggregateRoot)
{
	DatabaseType databaseType = RetrieveDatabaseTypeFrom(aggregateRoot);
	_objectContextFactory.Create().UpdateEntity<DatabaseType>(databaseType);
}

public void PersistDeletion(IAggregateRoot aggregateRoot)
{
	DatabaseType databaseType = RetrieveDatabaseTypeFrom(aggregateRoot);
	_objectContextFactory.Create().DeleteEntity<DatabaseType>(databaseType);
}

private DatabaseType RetrieveDatabaseTypeFrom(IAggregateRoot aggregateRoot)
{
	DomainType domainType = (DomainType)aggregateRoot;
	DatabaseType databaseType = ConvertToDatabaseType(domainType);
	return databaseType;
}

We need to convert the incoming IAggregateRoot object to the database type as it is the database type that the DB understands. The DB type is its own representation of the domain so we need to talk to it that way.

So these are the persistence methods but we need to register the changes first. Add the following methods to Repository.cs:

public void Update(DomainType aggregate)
{
	_unitOfWork.RegisterUpdate(aggregate, this);
}

public void Insert(DomainType aggregate)
{
	_unitOfWork.RegisterInsertion(aggregate, this);
}

public void Delete(DomainType aggregate)
{
	_unitOfWork.RegisterDeletion(aggregate, this);
}

These operations are so common and repetitive that we can put them in this abstract base class instead of letting the domain-specific repositories implement them over and over again. All they do is adding the operations to the queue of the unit of work to be performed when Commit() is called. Upon Commit() the unit of work repository, i.e. the abstract Repository object will persist the changes using the in memory object context.

This model is relatively straightforward to change:

  • If you need a plain file-based storage mechanism then you might create a FileObjectContext class where you read to and from a file.
  • For EntityFramework and Linq to SQL you’ll use the built-in object context classes to keep track of and persist the changes
  • File-based NoSql solutions generally also have drivers for .NET – they can be used to implement a NoSql solution

So the possibilities are endless in fact. You can hide the implementation behind abstractions such as the IUnitOfWork interface or the Repository abstract class. It may well be that you need to add methods to the Repository class depending on the data storage technology you use but that’s perfectly acceptable. The concrete repository layer is…, well, concrete. You can dedicate it to a specific technology, just like the one we’re building here is dedicated to an in-memory storage mechanism. You can have several different implementations of the IUnitOfWork and IUnitOfWorkRepository interfaces and test them before you let your application go public. You can even mix and match the implementations:

  • Register the changes in a temporary file and commit them in NoSql
  • Register the changes in memory and commit them to the cache
  • Register the changes in cache and commit them to SQL Azure

Of course these combinations are very exotic but it shows you the flexibility behind all these abstractions. Don’t assume that the Repository class is a solution for ALL types of concrete unit of work. You’ll certainly have to modify it depending on the concrete data storage mechanism you work with. However, note the following points:

  • The rest of the application will not be concerned with the concrete data access implementation
  • The implementation details are well hidden behind this layer without them bubbling up to and permeating the other layers

So as long as the concrete implementations are hidden in the data access layer you’ll be fine.

There’s one last abstract method we’ll add to Repository.cs is the ubiquitous find-by-id method which we’ll delegate to the implementing classes:

public abstract DomainType FindBy(IdType id);

We’ll implement the CustomerRepository class in the next post.

View the list of posts on Architecture and Patterns here.

A model .NET web service based on Domain Driven Design Part 4: the abstract Repository

Introduction

In the previous post we created a very basic domain layer with the first domain object: Customer. We’ll now see what the data access layer could look like in an abstract form. This is where we must be careful not to commit the same mistakes as in the technology-driven example of the introductory post of this series.

We must abstract away the implementation details of the data access technology we use so that we can easily switch strategies later if necessary. We cannot let any technology-specific implementation bubble up from the data access layer. These details include the object context in EntityFramework, MongoClient and MongoServer in MongoDb .NET, the objects related to the file system in a purely file based data access solution etc., you probably get the idea. We must therefore make sure that no other layer will be dependent on the concrete data access solution.

We’ll first lay the foundations for abstracting away any type of data access technology and you may find it a “heavy” process with a steep learning curve. As these technologies come in many different shapes this is not the most trivial task to achieve. We can have ORM technologies like EntityFramework, file-based data storage like MongoDb, key-value style storage such as Azure storage, and it’s not easy to find a common abstraction that fits all of them. We’ll need to accommodate these technologies without hurting the ISP principle too much. We’ll follow a couple of well-established patterns and see how they can be implemented.

Aggregate root

We discussed aggregates and aggregate roots in this post. Recall that aggregates are handled as one unit where the aggregate root is the entry point, the “boss” of the aggregate. This implies that the data access layer should only handle aggregate roots. It should not accept objects that lie somewhere within the aggregate. We haven’t yet implemented any code regarding aggregate roots, but we can take a very simple approach. Insert the following empty interface in the Infrastructure.Common/Domain folder:

public interface IAggregateRoot
{
}

Conceptually it would probably be better to create a base class for aggregate roots, but we already have one for entities. As you know an object cannot derive from two base classes so we’ll indicate aggregate roots with this interface instead. At present it is simply an indicator interface with no methods, such as the ISerializable interface in .NET. We could add common properties or methods here but I cannot think of any right now.

After consulting the domain expert we decide that the Customer domain is an aggregate root: the root of its own Customer aggregate. Right now the Customer aggregate has only one member, the Customer entity, but that’s perfectly acceptable. Aggregate roots don’t necessarily consist of at least 2 objects. Let’s change the Customer domain object declaration as follows:

public class Customer : EntityBase<int>, IAggregateRoot

The rest of the post will look at how to abstract away the data access technology and some patterns related to that.

Unit of work

The first important concept within data access and persistence is the Unit of Work. The purpose of a Unit of Work is to maintain a list of objects that have been modified by a transaction. These modifications include insertions, updates and deletions. The Unit of Work co-ordinates the persistence of these changes and also checks for concurrency problems, such as the same object being modified by different threads.

This may sound a bit cryptic but if you’re familiar with EntityFramework or Linq to SQL then the object context in each technology is a good example for an implementation of a unit of work:

DbContext.AddObject("Customers", new Customer());
DbContext.SaveChanges();
DbContext.Customers.InsertOnSubmit(new Customer());
DbContext.SubmitChanges();

In both cases the DbContext, which takes the role of the Unit of Work, first registers the changes. The changes are not persisted until the SaveChanges() – EntityFramework – or the SubmitChanges() – Linq to SQL – method is called. Note that the DB object context is responsible for registering AND persisting the changes.

The Unit of Work pattern can be represented by the following interface:

public interface IUnitOfWork
{
	void RegisterUpdate(IAggregateRoot aggregateRoot);
	void RegisterInsertion(IAggregateRoot aggregateRoot);
	void RegisterDeletion(IAggregateRoot aggregateRoot);
	void Commit();
}

Notice that we have separated the registration and commit actions. In the case of EntityFramework and similar ORM technologies the object that registers and persists the changes will often be the same: the object context or a similar object.

However, this is not always the case. It is perfectly reasonable that you are not fond of these automation tools and want to use something more basic where you have the freedom of specifying how you track changes and how you persist them: you may register the changes in memory and persist them in a file. Or you may still have a lot of legacy ADO.NET where you want to move to a more modern layered architecture. ADO.NET lacks a DbContext object so you may have to solve the registration of changes in a different way.

For those scenarios we need to introduce another abstraction. Insert the following interface in a new folder called UnitOfWork in the Infrastructure layer:

public interface IUnitOfWorkRepository
{
	void PersistInsertion(IAggregateRoot aggregateRoot);
	void PersistUpdate(IAggregateRoot aggregateRoot);
	void PersistDeletion(IAggregateRoot aggregateRoot);
}

Insert a new interface called IUnitOfWork in the same folder:

public interface IUnitOfWork
{
	void RegisterUpdate(IAggregateRoot aggregateRoot, IUnitOfWorkRepository repository);
	void RegisterInsertion(IAggregateRoot aggregateRoot, IUnitOfWorkRepository repository);
	void RegisterDeletion(IAggregateRoot aggregateRoot, IUnitOfWorkRepository repository);
	void Commit();
}

The above Unit of Work pattern abstraction can be extended as above to give way for the total separation between the registration and persistence of aggregate roots. Later on, as we see these elements at work and as you get more acquainted with the structure of the solution, you may decide that this is overkill and you want to go with the more simple solution, it’s up to you.

Repository pattern

The repository pattern is used to declare the possible data access related actions you want to expose for your aggregate roots. The most basic of those are CRUD operations: insert, update, delete, select. You can have other methods such as insert many, select by ID, select by id and date etc., but the CRUD operations are probably the most common across all aggregate roots.

It may be beneficial to divide those operations into two groups: read and write operations. You may have a read-only policy for some aggregate roots so you don’t need to expose all of those operations. For read-only aggregates you can have a read-only repository. Insert the following interface in the Domain folder of the Infrastructure project:

public interface IReadOnlyRepository<AggregateType, IdType> where AggregateType : IAggregateRoot
{
	AggregateType FindBy(IdType id);
	IEnumerable<AggregateType> FindAll();
}

Here again we only allow aggregate roots to be selected. Finding an object by its ID is such a basic operation that it just has to be included here. FindAll can be a bit more sensitive issue. If you have a data table with millions of rows then you may not want to expose this method as it will bog down your data server, so use it with care. It’s perfectly OK to omit this operation from this interface. You will be able to include this method in domain-specific repositories as we’ll see in the next post. E.g. if you want to enable the retrieval of all Customers from the database then you can expose this method in the CustomerRepository class.

The other data access operations can be exposed in an “actionable” interface. Insert the following interface in the folder of the Infrastructure project:

public interface IRepository<AggregateType, IdType> 
		: IReadOnlyRepository<AggregateType, IdType> where AggregateType 
		: IAggregateRoot
{
	void Update(AggregateType aggregate);
	void Insert(AggregateType aggregate);
	void Delete(AggregateType aggregate);
}

Keep in mind that these interfaces only expose the most common actions that are applicable across all aggregate roots. You’ll be able to specify domain-specific actions in domain-specific implementations of these repositories.

We’ll look at how these elements can be implemented for the Customer object in the next post.

View the list of posts on Architecture and Patterns here.

A model .NET web service based on Domain Driven Design Part 3: the Domain

Introduction

In the previous post we laid the theoretical foundation for our domains. Now it’s finally time to see some code. In this post we’ll concentrate on the Domain layer and we’ll also start building the Infrastructure layer.

Infrastructure?

Often the word infrastructure is taken to mean the storage mechanism, like an SQL database, or the physical layers of a system, such as the servers. However, in this case we mean something different. The infrastructure layer is a place for all sorts of cross-cutting concerns and objects that can be used in any project. They are not specific to any single project or domain. Examples: logging, file operations, security, caching, helper classes for Date and String operations etc. Putting these in a separate infrastructure layer helps if you want to employ the same logging, caching etc. policy across all your projects. You could put these within the project solution but then when you start your next project then you may need to copy and paste a lot of code.

Infrastructure

The Entities we discussed in the previous post will all derive from an abstract EntityBase class. We could put it directly into the domain layer. However, think of this class as the base for all entities across all your DDD projects where you put all common functionality for your domains.

Create a new blank solution in VS and call it DDDSkeletonNET.Portal. Add a new C# class library called DDDSkeletonNET.Infrastructure.Common. Remove Class1 and add a new folder called Domain. In that folder add a new class called EntityBase:

public abstract class EntityBase<IdType>
{
	public IdType Id { get; set; }

	public override bool Equals(object entity)
	{
		return entity != null
		   && entity is EntityBase<IdType>
		   && this == (EntityBase<IdType>)entity;
	}

	public override int GetHashCode()
	{
		return this.Id.GetHashCode();
	}

	public static bool operator ==(EntityBase<IdType> entity1, EntityBase<IdType> entity2)
	{
		if ((object)entity1 == null && (object)entity2 == null)
		{
			return true;
		}

		if ((object)entity1 == null || (object)entity2 == null)
		{
			return false;
		}

		if (entity1.Id.ToString() == entity2.Id.ToString())
		{
			return true;
		}

		return false;
	}

	public static bool operator !=(EntityBase<IdType> entity1, EntityBase<IdType> entity2)
	{
		return (!(entity1 == entity2));
	}
}

We only have one property at this point, the ID, whose type can be specified through the IdType type parameter. Often this will be an integer or maybe a GUID or even some auto-generated string. The rest of the code takes care of comparison issues so that you can compare two entities with the ‘==’ operator or the Equals method. Recall that entityA == entityB if an only if their IDs are identical, hence the comparison being based on the ID property.

Domains need to validate themselves when insertions or updates are executed so let’s add the following abstract method to EntityBase.cs:

protected abstract void Validate();

We can describe our business rules in many ways but the simplest format is a description in words. Add a class called BusinessRule to the Domain folder:

public class BusinessRule
{
	private string _ruleDescription;

	public BusinessRule(string ruleDescription)
	{
		_ruleDescription = ruleDescription;
	}

	public String RuleDescription
	{
		get
		{
			return _ruleDescription;
		}
	}
}

Coming back to EntityBase.cs we’ll store the list of broken business rules in a private variable:

private List<BusinessRule> _brokenRules = new List<BusinessRule>();

This list represents all the business rules that haven’t been adhered to during the object composition: the total price is incorrect, the customer name is empty, the person’s age is negative etc., so it’s all the things that make the state of the object invalid. We don’t want to save objects in an invalid state in the data storage, so we definitely need validation.

Implementing entities will be able to add to this list through the following method:

protected void AddBrokenRule(BusinessRule businessRule)
{
	_brokenRules.Add(businessRule);
}

External code will collect all broken rules by calling this method:

public IEnumerable<BusinessRule> GetBrokenRules()
{
	_brokenRules.Clear();
	Validate();
	return _brokenRules;
}

We first clear the list so that we don’t return any previously stored broken rules. They may have been fixed by then. We then run the Validate method which is implemented in the concrete domain classes. The domain will fill up the list of broken rules in that implementation. The list is then returned. We’ll see in a later post on the application service layer how this method can be used from the outside.

We’re now ready to implement the first domain object. Add a new C# class library called DDDSkeleton.Portal.Domain to the solution. Let’s make this easy for us and create the most basic Customer domain. Add a new folder called Customer and in it a class called Customer which will derive from EntityBase.cs. The Domain project will need to reference the Infrastructure project. Let’s say the Customer will have an id of type integer. At first the class will look as follows:

public class Customer : EntityBase<int>
{
	protected override void Validate()
	{
		throw new NotImplementedException();
	}
}

We know from the domain expert that every Customer will have a name, so we add the following property:

public string Name { get; set; }

Our first business rule says that the customer name cannot be null or empty. We’ll store these rule descriptions in a separate file within the Customer folder:

public static class CustomerBusinessRule
{
	public static readonly BusinessRule CustomerNameRequired = new BusinessRule("A customer must have a name.");
}

We can now implement the Validate() method in the Customer domain:

protected override void Validate()
{
	if (string.IsNullOrEmpty(Name))
	{
		AddBrokenRule(CustomerBusinessRule.CustomerNameRequired);
	}
}

Let’s now see how value objects can be used in code. The domain expert says that every customer will have an address property. We decide that we don’t need to track Addresses the same way as Customers, i.e. we don’t need to set an ID on them. We’ll need a base class for value objects in the Domain folder of the Infrastructure layer:

public abstract class ValueObjectBase
{
	private List<BusinessRule> _brokenRules = new List<BusinessRule>();

	public ValueObjectBase()
	{
	}

	protected abstract void Validate();

	public void ThrowExceptionIfInvalid()
	{
		_brokenRules.Clear();
		Validate();
		if (_brokenRules.Count() > 0)
		{
			StringBuilder issues = new StringBuilder();
			foreach (BusinessRule businessRule in _brokenRules)
			{
				issues.AppendLine(businessRule.RuleDescription);
			}

			throw new ValueObjectIsInvalidException(issues.ToString());
		}
	}

	protected void AddBrokenRule(BusinessRule businessRule)
	{
		_brokenRules.Add(businessRule);
	}
}

…where ValueObjectIsInvalidException looks as follows:

public class ValueObjectIsInvalidException : Exception
{
     public ValueObjectIsInvalidException(string message)
            : base(message)
        {}
}

You’ll recognise the Validate and AddBrokenRule methods. Value objects can of course also have business rules that need to be enforced. In the Domain layer add a new folder called ValueObjects. Add a class called Address in that folder:

public class Address : ValueObjectBase
{
	protected override void Validate()
	{
		throw new NotImplementedException();
	}
}

Add the following properties to the class:

public string AddressLine1 { get; set; }
public string AddressLine2 { get; set; }
public string City { get; set; }
public string PostalCode { get; set; }

The domain expert says that every Address object must have a valid City property. We can follow the same structure we took above. Add the following class to the ValueObjects folder:

public static class ValueObjectBusinessRule
{
	public static readonly BusinessRule CityInAddressRequired = new BusinessRule("An address must have a city.");
}

We can now complete the Validate method of the Address object:

protected override void Validate()
{
	if (string.IsNullOrEmpty(City))
	{
		AddBrokenRule(ValueObjectBusinessRule.CityInAddressRequired);
	}
}

Let’s add this new Address property to Customer:

public Address CustomerAddress { get; set; }

We’ll include the value object validation in the Customer validation:

protected override void Validate()
{
	if (string.IsNullOrEmpty(Name))
	{
		AddBrokenRule(CustomerBusinessRule.CustomerNameRequired);
	}
	CustomerAddress.ThrowExceptionIfInvalid();
}

As the Address value object is a property of the Customer entity it’s practical to include its validation within this Validate method. The Customer object doesn’t need to concern itself with the exact rules of an Address object. Customer effectively tells Address to go and validate itself.

We’ll stop building our domain layer now. We could add several more domain objects but let’s keep things as simple as possible so that you will be able to view the whole system without having to track too many threads. We now have an example of an entity, a value object and a couple of basic validation rules. We have missed how aggregate roots play a role in code but we’ll come back to that in the next post. You probably want to see how the repository, service and UI layers can be wired together.

We’ll start building the repository layer in the next post.

View the list of posts on Architecture and Patterns here.

A model .NET web service based on Domain Driven Design Part 2: DDD basics

Introduction

In the previous post we discussed how a traditional data access based layering can cause grief and sorrow. We’ll now move on to a better design and we’ll start with – what else – the domain layer. It is the heart of software, as Eric Evans put it, which should be the centre of the application. It should reflect our business entities and rules as close as possible. It will be an ever-evolving layer where you add, modify and remove bits of code as you get to know the domain better and better. The initial model will grow to a deep model with experimenting, brainstorming and knowledge crunching.

Before we dive into any code we have to discuss a couple of important terms. The domain layer is so important that an entire vocabulary has evolved around it. I promise to get to some real C# code after the theory.

Entities and value objects

Domain objects can be divided into entities and value objects.

An entity is an object with a unique ID. This unique ID is the most important property of an entity: it helps distinguish between two otherwise identical objects. We can have two people with the same name but if their IDs are different then we’re talking about two different people. Also, a person can change his/her name, but if the ID is the same then we know we’re talking about the same person. An ID is typically some integer or a GUID or some other string value randomly generated based on some properties of the object. Once the entity has been persisted, its ID should never change otherwise we lose track of it. In Sweden every legal person and company receives a personal registration number. Once you are given this ID it cannot be changed. From the point of view of the Swedish authorities this ID is my most important “property”. EntityA == EntityB if and only if EntityA.ID == EntityB.ID. Entities should ideally remain very clean POCO objects without any trace of technology-specific code. You may be tempted to add technology specific elements such s MVC attributes in here, e.g. [Required] or [StringLength(80)]. DON’T DO THAT. EVER! We’ll see later where they belong.

A value object on the other hand lacks any sort of ID. E.g. an office building may have 100 windows that look identical. Depending on your structure of the building you may not care which exact window is located where. Just grab whichever and mount it in the correct slot. In this case it’s futile to assign an ID to the window, you don’t care which one is which. Value objects are often used to group certain properties of an Entity. E.g. a Person entity can have an Address property which includes other properties such as Street and City. In your business an Address may well be a value object. In other cases, such as a postal company business, an Address will almost certainly be an Entity. A value object can absolutely have its own logic. Note that if you save value objects in the database it’s reasonable to assume that they will be assigned an automatic integer ID, but again – that’s an implementation detail that only concerns how our domain is represented in the storage, the domain layer doesn’t care, it will ignore the ID assigned by the data storage mechanism.

Sometimes it’s not easy to decide whether a specific object is an entity or a value object. If two objects have identical properties but we still need to distinguish between them then it’s most likely an entity with a unique ID. If two objects have identical properties and we don’t care which one is which: a value object. If the same object can be shared, e.g. the same Name can be attached to many Person objects: most likely a value object.

Aggregates and aggregate roots

Objects are seldom “independent”: they have other objects attached to them or are part of a larger object graph themselves. A Person object may have an Address object which in turn may have other Person objects if more than one person is registered there. It can be difficult to handle in software: if we delete a Person, then do we delete the Address as well? Then other Person objects registered there may be “homeless”. We can leave the Address in place, but then the DB may be full of empty, redundant addresses. Objects may therefore have a whole web of interdependency. Where does an object start and end? Where are its boundaries? There’s clearly a need to organise the domain objects into logical groups, so-called aggregates. An aggregate is a group of associated objects that are treated as a unit for the purpose of data changes. Every aggregate has a root and clear boundaries. The root is the only member of an aggregate that outside objects are allowed to hold references to.

Example

Take a Car object: it has a unique ID, e.g. the registration number to distinguish it from other cars. Each tire must also be measured somehow, but it’s unlikely that they will be treated separately from the car they belong to. It’s also unlikely that we make a DB search for a tire to see which car it belongs to. Therefore the Car is an aggregate root whose boundary includes the tires. Therefore consumers of the Car object should not be able to directly change the tire settings of the car. You may go as far as hiding the tires entirely within the Car aggregate and only let outside callers “get in touch with them” through methods such as “MoveCarForward”. The internal logic of the Car object may well modify the tires’ position, but to the outside world that is not visible.

An engine will probably also have a serial number and may be tracked independently of the car. It may happen that the engine is the root of its own aggregate and doesn’t lie within the boundaries of the Car, it depends on the domain model of the application.

Car aggregate root

An important term in conjunction with Aggregates is invariants. Invariants are consistency rules that must be maintained whenever data changes, so they represent business rules.

General guidelines for constructing the domain layer

Make sure that you allocate the best and most experienced developers available at your company to domain-related tasks. Often experienced programmers spend their time on exploring and testing new technologies, such as WebSockets. Entry-level programmers are then entrusted to construct the domain layer as technologically it’s not too difficult: write abstract and concrete classes, interfaces, methods, properties, that’s it really. Every developer should be able to construct these elements after completing a beginners’ course in C#. So people tend to think that this is an entry-level task. However, domain modelling and writing code in a loosely coupled and testable manner are no trivial tasks to accomplish.

Domains are the most important objects in Domain Driven Design. They are the objects that describe our business. They are so central that you should do your utmost to keep them clean, well organised and testable. It is worth building a separate Domain layer even during the mockup phase of a new project, even if you ignore the other layers. If you need to allocate time to maintain each layer within your solution then this layer should be allocated the most. This is important to keep in mind because you know how it usually goes with test projects – if management thinks it’s good then you often need to continue to build upon your initial design. There’s no time to build a better application because suddenly you are given a tight deadline. Then you’re stuck with a domain-less solution.

Domain objects should always be the ones that take priority. If you have to change the domain object to make room for some specific technology, then you’re taking the wrong direction. It is the technology that must fit the domain objects, not vice versa.

Domain objects are also void of persistence-related code making them technology agnostic or persistence ignorant. A Customer object will not care how it is stored in a database table, that is an irrelevant implementation detail.

Domain objects should be POCO and void of technology-specific attributes, such as the ones available in standard MVC, e.g. [Required]. Domain objects should be clear of all such ‘pollution’. Also, all logic specific to a domain must be included in the domain. These business rules contain validation rules as well, such as “the quantity should not be negative” or “a customer must not buy more than 5 units of this product”. Resist the temptation to write external files, such as CustomerHelper etc. where you put domain-specific logic, that’s not right. A domain is responsible to implement its specific domain logic. Example: in a banking application we may have an Account domain with a rule saying that the balance cannot be negative. You must include this validation logic within Account.cs, not in some other helper class. If the Account class has a complex validation logic then it’s fine to factor out the IMPLEMENTATION of the validation. i.e. the method body to a separate helper class. However, having a helper class that totally encapsulates domain validation and other domain-specific logic is the incorrect approach. Consumers of the domain will not be aware that there is some external class that they need to call. If domain specific logic is placed elsewhere then not even a visual inspection of the class file will reveal the domain logic to the consumer.

Make sure to include logic specific to a single domain object. Example: say you have an object called Observation with two properties of type double: min and max. If you want to calculate the average then Observation.cs will have a method called CalculateAverage and return the average of min and max, i.e. it performs logic on the level of a single domain object.

In the next post we’ll look at how these concepts can be written in code.

View the list of posts on Architecture and Patterns here.

A model .NET web service based on Domain Driven Design Part 1: introduction

Introduction

Layered architecture has been the norm in enterprise projects for quite some time now. We layer our solutions into groups of responsibilities: UI, services, data access, infrastructure and others. We can connect these layers by setting references to them from the consuming layer. There are various ways to set these layers and references. The choices you make here depend on the project type – Web, WPF, WCF, games etc. – you’re working on and the philosophy you follow.

On the one hand you may be very technology driven and base your choices primarily on the technologies available to build your project: Entity Framework, Ajax, MVC etc. Most programmers are like that and that’s natural. It’s a safe bet that you’ve become a developer because you’re interested in computers and computer-related technologies like video games and the Internet. It’s exciting to explore and test new technologies as they emerge: .NET, ORM, MVC, WebAPI, various JavaScript libraries, WebSockets, HighCharts, you name it. In fact, you find programming so enthralling that you would keep doing it for free, right? Just don’t tell your boss about it in the next salary review… With this approach it can happen in a layered architecture that the objects in your repository layer, i.e. the data access layer, such as an SQL Server database, will receive the top focus in your application. This is due to the popular ORM technologies available in .NET: EntityFramework and Linq to SQL. They generate classes based on some database representation of your domain objects. All other layers will depend on the data access layer. We’ll see an example of this below.

On the other hand you may put a different part of the application to the forefront: the domain. What is the domain? The domain describes your business. It is a collection of all concepts and logic that drive your enterprise. If you follow this type of philosophy, which is the essence of Domain Driven Design (DDD), then you give the domain layer the top priority. It will be the most important ingredient of the application. All other layers will depend on the domain layer. The domain layer will be an entirely independent one that can function on its own. The most important questions won’t be “How do we solve this with WebSockets?” or “How does it work with AngularJs?” but rather like these ones:

  • How does the Customer fit into our domain?
  • Have we modelled the Product domain correctly?
  • Is this logic part of the Product or the OrderItem domain?
  • Where do we put the pricing logic?

Technology-related questions will suddenly become implementation details where the exact implementation type can vary. We don’t really care which graph package we use: it’s an implementation detail. We don’t really care which ORM technology we use: it’s an implementation detail.

Of course technology-related concerns will be important aspects of the planning phase, but not as important as how to correctly represent our business in code.

In a technology-driven approach it can easily happen that the domain is given low priority and the technology choices will directly affect the domain: “We have to change the Customer domain because its structure doesn’t fit Linq to SQL”. In DDD the direction is reversed: “An important part of our Customer domain structure has changed so we need to update our Linq to SQL classes accordingly.”. A change in the technology should never force a change in your domain. Your domain is an independent entity that only changes if your business rules change or you discover that your domain logic doesn’t represent the true state of things.

Keep in mind that it is not the number of layers that makes your solution “modern”. You can easily layer your application in a way that it becomes a tightly coupled nightmare to work with and – almost – impossible to extend. If you do it correctly then you will get an application that is fun and easy to work with and is open to all sorts of extensions, even unanticipated ones. This last aspect is important to keep in mind. Nowadays customers’ expectations and wishlists change very often. You must have noticed that the days of waterfall graphs, where the the first version of the application may have rolled out months or even years after the initial specs were written, are over. Today we have a product release every week almost where we work closely with the customer on every increment we build in. Based on these product increments the customer can come with new demands and you better be prepared to react fast instead of having to rewrite large chunks of your code.

Goals of this series

I’ll start with stating what’s definitely not the goal: give a detailed account on all details and aspects of DDD. You can read all about DDD by its inventor Eric Evans in this book. It’s a book that discusses all areas of DDD you can think of. It’s no use regurgitating all of that in these posts. Also, building a model application which uses all concepts from DDD may easily grow into full-fledged enterprise application, such as SAP.

Instead, I’ll try to build the skeleton of a .NET solution that takes the most important ideas from DDD. The result of this skeleton will hopefully be a solution that you can learn from and even tweak it and use in your own project. Don’t feel constrained by this specific implementation – feel free to change it in a way that fits your philosophy.

However, if you’re completely new to DDD then you should still benefit from these posts as I’ll provide explanations for those key concepts. I’ll try to avoid giving you too much theory and rather concentrate on code but some background must be given in order to explain the key ideas. We’ll need to look at some key terms before providing any code. I’ll also refer to ideas from SOLID here and there – if you don’t understand this term then start here.

Also, it would be great to build the example application with TDD, but that would add a lot of noise to the main discussion. If you don’t know what TDD means, start here.

The ultimate goal is to end up with a skeleton solution with the following layers:

  • Infrastructure: infrastructure services to accommodate cross-cutting concerns
  • Data access (repository): data access and persistence technology layer, such as EntityFramework
  • Domain: the domain layer with our business entities and logic, the centre of the application
  • Application services: thin layer to provide actions for the consumer(s) such as a web or desktop app
  • Web: the ultimate consumer of the application whose only purpose is to show data and accept requests from the user

…where the layers communicate with each other in a loosely coupled manner through abstractions. It should be easy to replace an implementation with another. Of course writing a new version of – say – the repository layer is not a trivial task and layering won’t make it easier. However, the switch to the new implementation should go with as little pain as possible without the need to modify any of the other layers.

The Web layer implementation will actually be a web service layer using the Web API technology so that we don’t need to waste time on CSS and HTML. If you don’t know what Web API is about, make sure you understand the basics from this post.

UPDATE: the skeleton application is available for download on GitHub here.

Doing it wrong

Let’s take an application that is layered using the technology-driven approach. Imagine that you’ve been tasked with creating a web application that lists the customers of the company you work for. You know that layered architectures are the norm so you decide to build these 3 layers:

  • User Interface
  • Domain logic
  • Data access

You know more or less what the Customer domain looks like so you create the following table in SQL Server:

Customer table in SQL Server

Then you want to use the ORM capabilities of Visual Studio to create the Customer class for you using the Entity Framework Data Model Wizard. Alternatively you could go for a Linq to SQL project type, it doesn’t make any difference to our discussion. At this point you’re done with the first layer in your project, the data access one:

Entity Framework model context

EntityFramework has created a DbContext and the Customer class for us.

Next, you know that there’s logic attached to the Customer domain. In this example we want to refine the logic of what price reduction a customer receives when purchasing a product. Therefore you implement the Domain Logic Layer, a C# class library. To handle Customer-related queries you create a CustomerService class:

public class CustomerService
{
	private readonly ModelContext _objectContext;

	public CustomerService()
	{
		_objectContext = new ModelContext();
	}

	public IEnumerable<Customer> GetCustomers(decimal totalAmountSpent)
	{
		decimal priceDiscount = totalAmountSpent > 1000M ? .9m : 1m;
		List<Customer> allCustomers = (from c in _objectContext.Customers select c).ToList();
		return from c in allCustomers select new Customer()
		{
			Address = c.Address
			, DiscountGiven = c.DiscountGiven * priceDiscount
			, Id = c.Id
			, IsPreferred = c.IsPreferred
			, Name = c.Name
		};
	}
}

As you can see the final price discount depends also on the amount of money spent by the customer, not just the value currently stored in the database. So, that’s some extra logic that is now embedded in this CustomerService class. If you’re familiar with SOLID then the ‘_objectContext = new ModelContext();’ part immediately raises a warning flag for you. If not, then make sure to read about the Dependency Inversion Principle.

In order to make this work I had to add a library reference from the domain logic to the data access layer. I also had to add a reference to the EntityFramework library due to the following exception:

The type ‘System.Data.Entity.DbContext’ is defined in an assembly that is not referenced. You must add a reference to assembly ‘EntityFramework, Version=4.4.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089’.

So I import the EntityFramework library into the DomainLogic layer to make the project compile.

At this point I have the following projects in the solution:

Data access and domain logic layer

The last layer to add is the UI layer, we’ll go with an MVC solution. The Index() method which lists all customers might look like the following:

public class HomeController : Controller
{
	public ActionResult Index()
	{
		decimal totalAmountSpent = 1000; //to be fetched with a different service, ignored here
		CustomerService customerService = new CustomerService();
		IEnumerable<Customer> customers = customerService.GetCustomers(totalAmountSpent);
		return View(customers);
	}	
}

In order to make this work I had to reference both the DomainLogic AND the DataAccess projects from the UI layer. I now have 3 layers in the solution:

DDD three layers

So I press F5 and… …get an exception:

“No connection string named ‘ModelContext’ could be found in the application config file.”

This exception is thrown at the following line within CustomerService.GetCustomers:

List<Customer> allCustomers = (from c in _objectContext.Customers select c).ToList();

The ModelContext object implicitly expects that a connection string called ModelContext is available in the web.config file. It was originally inserted into app.config of the DataAccess layer by the EntityFramework code generation tool. So a quick fix is to copy the connection string from this app.config to web.config of the web UI layer:

<connectionStrings> 
    <add name="ModelContext" connectionString="metadata=res://*/Model.csdl|res://*/Model.ssdl|res://*/Model.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=mycomputer;initial catalog=Test;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" />
</connectionStrings>

Evaluation

Have we managed to build a “modern” layered application? Well, we certainly have layers, but they are tightly coupled. Both the UI and the Logic layer are strongly dependent on the DataAccess layer. Examples of tight coupling:

  • The HomeController/Index method constructs a CustomerService object
  • The HomeController/Index directly uses the Customer object from the DataAccess layer
  • The CustomerService constructs a new ModelContext object
  • The UI layer is forced to include an EntityFramework-specific connection string in its config file

At present we have the following dependency graph:

DDD wrong dependency graph

It’s immediately obvious that the UI layer can easily bypass any logic and consult the data access layer directly. It can read all customers from the database without applying the extra logic to determine the price discount.

Is it possible to replace the MVC layer with another UI type, say WPF? It certainly is, but it does not change the dependency graph at all. The WPF layer would also need to reference both the Logic and the DataAccess layers.

Is it possible to replace the data access layer? Say you’re done with object-relational databases and want to switch to file-based NoSql solutions such as MongoDb. Or you might want to move to a cloud and go with an Azure key-value type of storage. We don’t need to go as far as entirely changing the data storage mechanism. What if you only want to upgrade your technology Linq to SQL to EntityFramework? It can be done, but it will be a difficult process. Well, maybe not in this small example application, but imagine a real-world enterprise app with hundreds of domains where the layers are coupled to such a degree with all those references that removing the data access layer would cause the application to break down immediately.

The ultimate problem is that the entire domain model is defined in the data access layer. We’ve let the technology – EntityFramework – take over and it generated our domain objects based on some database representation of our business. It is an entirely acceptable solution to let an ORM technology help us with programming against a data storage mechanism in a strongly-typed object-oriented fashion. Who wants to work with DataReaders and SQL commands in a plain string format nowadays? However, letting some data access automation service take over our core business and permeate the rest of the application is far from desirable. The CustomerService constructor tightly couples the DomainLogic to EntityFramework. Since we need to reference the data access layer from within our UI even the MVC layer is coupled to EntityFramework. In case we need to change the storage mechanism or the domain logic layers we potentially have a considerable amount of painful rework to be done where you have to manually overwrite e.g. the Linq to SQL object context references to EntityFramework object context ones.

We have failed miserably in building a loosely coupled, composable application whose layers have a single responsibility. The domain layer, as stated in the introduction, should be the single most important layer in your application which is independent of all other layers – possibly with the exception of infrastructure services which we’ll look at in a later post in this series. Instead, now it is a technological data access layer which rules and where the domain logic layer is relegated to a second-class citizen which can be circumvented entirely.

The domain is at the heart of our business. It exists regardless of any technological details. If we sell cars, then we sell cars even if the car objects are stored in an XML file or in the cloud. It is a technological detail how our business is represented in the data storage. It is something that the Dev department needs to be concerned with. The business rules and domains have a lot higher priority than that: it is known to all departments of the company.

Another project type where you can easily confuse the roles of each layer is ASP.NET WebForms with its code behind. It’s very easy to put a lot of logic, database calls, validation etc. into the code-behind file. You’ll soon end up with the Smart UI anti-pattern where the UI is responsible for all business aspects of your application. Such a web application is difficult to compose, unit test and decouple. This doesn’t mean that you must forget WebForms entirely but use it wisely. Look into the Model-View-Presenter pattern, which is sort of MVC for WebForms, and then you’ll be fine.

So how can we better structure our layers? That will be the main topic of the series. However, we’ll need to lay the foundation for our understanding with some theory and terms which we’ll do in the next post.

View the list of posts on Architecture and Patterns here.

Elliot Balynn's Blog

A directory of wonderful thoughts

Software Engineering

Web development

Disparate Opinions

Various tidbits

chsakell's Blog

WEB APPLICATION DEVELOPMENT TUTORIALS WITH OPEN-SOURCE PROJECTS

Once Upon a Camayoc

ARCHIVED: Bite-size insight on Cyber Security for the not too technical.