6

Im currently trying to refactor a project(asp.net mvc) that doesnt have any separation at all. just folders :s

  • The project has a bunch of EF Code First classes (People.cs, Exam.cs, Message.cs, etc)
  • The project has several repositories (which all use EF Data Context)
  • And of course a lot of controllers and viewmodels

We have a Tests Project but we arent very good at TDD so its not something we are really working on as of now.

I would like to have a clearer separation on the different responsibilities that the project has to address and would appreciate some advice on a good project structure that achieves this.

Please help. thanks in advance

nacho10f
  • 5,816
  • 6
  • 42
  • 73

2 Answers2

12

I would suggest following a Domain Driven Design (DDD) and one suggested way of laying this out would be creating the following projects:

Company.Project.Web <-- Your MVC Application, though you can still use WebForms Company.Project.Domain <-- Data Transfer Objects (DTO's), ViewModels, Business Logic, Events Company.Project.Data <-- Repository Interfaces

Company.Project.Data.EF <-- EntityFramework Specific Implementation of Repositories Company.Project.Model <-- Your EF CodeFirst Classes

Company.Common <-- A common project of utilities and/or extensions

I would suggest you take a look at Project Silk http://silk.codeplex.com/ from the patterns and practices team. Great reference implementation of DDD, Repository, and MVC as well as mixing in HTML 5 and jQuery (vNext).

jdmonty
  • 2,293
  • 1
  • 14
  • 11
  • Agreed with adding the Interfaces - and I'd chuck in using an IoC container to take care of resolving the interface to implementation at runtime. – Michael Shimmins Jul 29 '11 at 03:00
  • I have read that viewModels are not supposed to interact with service layer (business logic) at all. shouldnt they remain the web project? – nacho10f Jul 29 '11 at 03:14
  • We generally keep the ViewModels in the Web project. Although, our DTO's can be used directly by the presentation layer be it Web or Services or WPF (XAML). IoC container such as Unity is a must to keep our concerns separated and inject our service dependencies. – jdmonty Jul 29 '11 at 13:41
  • 1
    I like the viewModels being in the domain layer. Whether you edit a customer in a browser or in a phone app, the viewModel itself is the same – MikeT Dec 15 '15 at 20:40
  • The link to Project Silk (http://silk.codeplex.com/) is no longer active. Not sure if this link is a good replacement? (https://download.microsoft.com/download/3/7/D/37D7AFAD-8714-4D5F-B1C1-11F9130F15DD/Microsoft%20Project%20Silk.pdf) – jnt Dec 17 '19 at 14:48
11

We use a similar design to that mentioned by jdmonty but a bit simpler. We do the following:

  • ApplicationName.Web - MVC Application
  • ApplicationName.Services - Business logic
  • ApplicationName.Domain - EF CodeFirst classes and the repositories that act on them
  • ApplicationName.Common - Classes and utilities used by multiple projects
  • ApplicationName.Tests - Test for the various projects

The Web project is dependent upon the Services project. The Services project is dependent upon the Domain project.

Nick Olsen
  • 6,299
  • 11
  • 53
  • 75
  • Thanks for this advice. it looks pretty clean... would you mind giving a little more detail on where you keep your ViewModels?... do they interact with Services project? – nacho10f Jul 29 '11 at 03:13
  • 3
    We keep the ViewModels in the Web project because as you mentioned they should not interact with the Service layer at all. The ViewModels are solely to be used for transferring data between the Views and the Controller. – Nick Olsen Jul 29 '11 at 03:50
  • Nick, are you using DataAnnotations in your view models to validation ? If you do, could we say that these validations are also business logic ? – Fernando Vezzali Nov 16 '13 at 19:01
  • 2
    @FernandoAyrosaVezzali You bring up a good point. We do use DataAnnotations for our ViewModels which one might call business logic and thus you are starting to put business logic at the application view level. While one might argue this is breaking the separation of concerns, one has to draw the line somewhere. – Nick Olsen Nov 18 '13 at 14:42