The layers we use are:
- View (with strongly typed View Models)
- Controller
- View Model Service
- Business Services
- Repositories
- (EF) Contexts
Views - as thin as can be - no logic - just display
View Models - Strongly typed per view - don't contain Entities, but just the fields we want in any one view.
Controller - just routing and calls to VMS. Handles exceptions that bubble up from the lower levels by routing to error pages.
View Model Services - creates and unpacks view models into the EF entities. No data access logic. One VMS per controller. Makes heavy use of AutoMapper to transfer the view model's data into entities.
Business Services - main point of data access. One BS per controller. Uses as many repositories as required to do its job. Transaction scope controller here. The VMS makes a single call to the BS - which wraps all the necessary DB calls in a single transaction if required. We anticipate the BS making calls out to external services in future.
Repositories - One per (top level) entity - does all CRUD operations for a group of entities. Our entities are large, complex object graphs - so we handle the top-most parent per repository.
Contexts - thin wrappers around the EF generated contexts so they can me mocked.
In terms of MVC - The Model part is made up of everything below the controller.