Domain Model is Not Understandable

Feb 25, 2011 at 5:14 PM

Domain Model is not understandable it looks anemic. Since this is given as a guidance we should make it perfect .. If you have document about the Domain please share or may be a conversation about the domain can Change the System more understandable

May 4, 2011 at 4:53 PM


Mileage Stats has two model - one the data model (in MileageStats.Model) and a domain model (in MileageStates.ServicesModel).  The data model is anemic because we use the DbModelBuilder to define the schema, and avoid incorporating business or application logic in the data tier.  The domain model is not anemic as it contains calculated properties, validation attributes, etc.  The domain model may seem thin compared to a domain model for a desktop client application.  The nature of the request/response pipeline for web applications and services means that a traditional domain model would create a connected object graph on each request.  We wanted to limit the data loaded per request to just the parts of the domain model needed for communication to and from the client.  We also wanted the ability in the future to possibly expose application logic as a separate service. For these reasons, most of the business logic was factored into a business services layer (in MileageStats.Services) which implements interfaces (in MileageStats.ServiceContracts).

We are currently working on the web guidance book (and help topics) that will explain the domain and data models in more detail (see the Drop 8 Server-side Architecture chapter).  However, it would be helpful if you can provide more details on what aspects of the domain model you found confusing. 

Were you confused by there being both a domain and a data model?

Was the class hierarchy of the domain model  confusing?

Are there code comments in the domain model you think we should add to clarify its purpose?

Is there a different architectural approach to separating concerns that you are more familiar with - possibly that we could compare/contrast to?

Thanks for you feedback,

Geoff Cox
Southworks, Inc.
on behalf of Microsoft Patterns & Practices


May 8, 2011 at 2:56 AM
Edited May 8, 2011 at 2:58 AM

Ya whatever u r saying go in hand with the CQRS where they have two model one is just for read and another one for Domain..And Domain need not have to have more associations .. which should have been behavioural in nature

Jul 15, 2011 at 7:04 AM


We are currently implementing a solution based on the Project Silk architecture and this topic came up today with a co-worker.

In the above post, you say that you wanted to "limit the data loaded per request to just the parts of the domain model needed for communication to and from the client." and that it "contains calculated properties".

However if in one of those calculated properties on a service model object you did need to access the database for some reason what approach would you recommend? I thought of the following 2 approaches:

* The Service model object could have an additional constructor containing an interface to a repository. This constructor could be called from a concrete service and the service model object could then use the repository to call into the database. However like a concrete service class it would have to handle the mapping between Data Model and Service Model. 

* The Service model object could contain a reference back to the concrete service that instantiated it and delegate all work back to it? The service would then call into the repository and do all the associated mapping etc. But this way would have a circular reference between the Service Model and Services projects...

* something else? Is there a better way?


Jul 19, 2011 at 6:23 PM

I would opt for something similar to your option 1 since circular references are usually a sign that there is something less than optimal in the design. :)

At one point, as the code was evolving into its current form, we had service model implementations that took several repositories as constructor arguments.  At this point, the handlers have the responsibilities for cross-repository changes.  Take a look at the the CreateVehicle handler in MileageStats.Domain\Handlers for an example.  

I see the read-only and/or cross-repository calculations working in a similar way in most situations.

I hope that helps,
Michael Puleio

Jul 21, 2011 at 6:20 AM

Thanks Michael - that clears it up for me