(Note – this is part of a series on MushMud.com – an ASP.NET/MVC/DDD Example. Be sure to read the introduction.)
From 1,000 feet the architecture looks like this:

and the solution like this:

(Note the root namespace is “MusicCompany” – that was what I named it before MushMud came along. Plus I don’t like the code-base so coupled to a specific domain name…)
Let’s start with Core.
The Core is what I like to think of as the heart of the application – where essential functionality if the system is implemented. The Core is where the domain model lives. The domain-model consists of the entities that represent the mental-model we have of our domain – things like Artists, Works, Licenses, Images and Audio Files. In terms of code, the main job of an entity is to enforce the invariant rules of the domain. The specifics of how the domain entity classes are designed and how they work together will be addressed later. The domain entities are the most essential part of the system, and deserve a blog post to themselves.
In addition to the domain entities, we also need a couple of other types of classes to get the core work done: Factories to help create new instances of entities, and Domain-Services to perform work involving multiple entities, factories and other external services.
A central part of this domain deals with audio files, formats, conversions and so forth. Most of this functionality is available in external libraries and open source code which I access through the domain services.
Here’s a snapshot of part of the Core project:

Note that the Services are defined as interfaces. For example the IMP3StreamService defines an interface for a service that performs data conversion between wave and mp3 encoded streams.

An actual implementation of this is in the MusicCompany.Core.Services.AudioConversion project, which utilizes a runtime-callable-wrapper of the LAME library (lame_enc.dll). There are similar interfaces and implementations for FLAC, Ogg and WAVE formats. I also use this same strategy for generating torrent files:

… with an implementation based on the MonoTorrent library. Here I pass in a CollectionWork (which is a domain entity) and get back a byte array representing the torrent definition which I can either write to disk or stream out.
Next I’ll address the Service Layer.
Not to be confused with Domain Services, the Service Layer is the surface area that is exposed to the user interface layers. Basically the service layer exposes an API that my web layer uses to get data in and out. This is a fundamental aspect to my overall architectural design: The core domain model is not used in the UI. Instead, a service layer based on requests and responses is exposed to the clients. I don’t pass entities in and out of the service layer – it takes in commands and queries and returns responses and data-transfer objects (DTOs). Getting to this point was a significant breakthrough in my architectural thinking, and is a concept that I think is being promoted by some really smart people. By building my service layer this way, I get several huge advantages:
- I can use the command pattern for each API operation. This promotes a testable design that follows the single-responsibility principle and promotes a beautiful level of intent and cohesion in the service layer classes.
- I don’t have to worry about data-binding issues in my entities. When doing data binding you often need special constructs like parameterless constructors, getters and setters for every field, property-changing notification, and hooks into UI-validation systems. I don’t want any of that in my entities, and I’ll go into more detail why later. Using a DTO or command object, I can easily databind to them because they are just simple data containers and by nature are essentially just get/set properties with a parameterlesss constructor.
- I don’t have to worry about the UI code calling methods on my entites – methods that perform domain logic that could potentially screw stuff up if used out of context. (Anti-Corruption Layer)
- If I want to switch to a sliverlight or a smart-client front end I can easily do so. (OK, maybe this is a YAGNI)
To accomplish this, I use the Agatha Request/Response Service Layer created by Davy Brion. Since this is a web app, I went with client-and-server-in-the-same-process configuration.
Here are the projects in the service layer:

The MusicCompany.Common project contiains classes that are references by both the consumer of the service layer (the UI) and the actual service layer processes (server components). The NHib project is to support reading theViewModel (DTOs) from the database – I don’t map my entities to DTOs, in fact I have two models – one for queries and one for executing commands. Or, as I sometimes think of it, a read model and a transactional model. I’ll get more into this later, as well.
A typical command looks like this:

Here we have the CreateArtistCommand, which inherits from CommandRequestBase, and CreateArtistCommandResponse, which inherits CommandResponseBase. My commands are not one-way, fire-and-forget type commands – I almost always want a response so I know it executed correctly, and sometimes for some additional data from the result of the command. This command has is constructed by the client when a user wants to create a new Artist entity. The properties of the command (OwningPersonName, ArtistName, Bio) are the essential data needed by the domain layer to perform this action. After the artist is created, the response sent back contains the Artist name – why? because sometimes the domain layer will need to make some adjustments to the string that the user supplied and we want to indicate what the name was actually saved as. Other uses of the response would be like “number of records affected”, etc.
The CommandRequestBase has the additional data that needs to be in all Commands – namely the context of command which lets us know who is issuing the command so that authentication and authorization can be done. By default, the context is anonymous.

And now, without further ado, the handler:

Pretty simple, eh? I love the one-method class. One thing to note is that I’m using the NHibernate ISession directly here, rather than using a Repository interface. This is something I contemplated quite a bit, and went back and forth on. I think, at the time I was reading a lot of Ayende which influenced the decision. If this were a larger, more “enterprisey” app I would probably go all out and use a repository for the sake of strict layering.
One great thing about Agatha, is that all I have to write are the command class, the command-response class and the command handler. Agatha takes care of all the plumbing to wire this all together, so that my UI just needs to create the command and hand it over to a request dispatcher instance (the client DOES NOT ever reference the command handlers).
Now lets look at Queries.
Actually, first I want to show a snapshot of what the project actually looks like when you’re in there:

Lots of files, huh? The nice thing is, each is for one distinct operation. I’d rather have this that a couple of classes with 20 or 30 methods each!
OK, a Query:

Same pattern as the command. A request and a response. The Request (the actual query object constructed by the client) contains a single property, ArtistIdentifier. This is the “parameter” for the query. If I need to add another parameter to the criteria, I just need to add a new property to query object. Compare that with a method on a repository or service that takes in x number of parameters…
The response to this query returns an IPagedList of TopLevelWorkSummaryView objects. So what’s a TopLevelWorkSummaryView? This is essentially a DTO that contains the data needed to display works in a list. The “top level” refers to works that do not have a parent work, such as a Collection (aka “album”) or a Single (song released as a single). Since all songs are Works, we don’t want to list songs that are part of a parent collection in this query, hence the TopLevel notion.
Now for the handler:

I’m using NHibernate.Linq here to query the data store for TopLevelWorkSummaryView objects that have an ArtistIdentifier matching the value in the request. TopLevelWorkSummaryView is a View in my database. This is what led to the xxxView nomenclature for the DTO classes. I realize this could be somewhat confusing compared to ViewModels in the MVC sense. Maybe next time I would name these xxxDTO. I also could actually persist these DTOs in a document database that I update with asynchronous events fired from the domain model, but I don’t need that degree of scalability yet. But, the groundwork is there if I ever need it.
Now for the UI.
The UI is where I actually spent the most time in this app, after the domain modeling. For one thing, I was learning ASP.NET MVC, which has a bit of learning curve. And also, I was learning jQuery, which is awesome but takes a little getting used to coming from ASP.NET Ajax. And I think that’s good – concentrate on the user experience and the presentation rather than worry about plumbing and infrastructure.
The Website project is laid out like a typical MVC project with controllers, views and viewmodels. One interesting aspect is my ExtendedController, which is a base class for my controllers. Here is a snippet:

The virtual ProcessRequest method is used by the concrete controllers to send all commands and queries to the service layer. So, for example the Index method of the home controller is like this:

In this case my “model” is an IndexViewModel. I went with the single view model per view pattern, so each view has it’s own view model with properties for all the data it needs. The home page needs two lists of works – the new releases and the most popular works, which are part of the ViewModel which the view can easily consume.
NEXT: The Domain Model – Commands and Transactions