ASP.NET MVC – Should MVC’s M, V, and C Be Aware of Domain Entities?

Architectureasp.net-mvcdesignentity-framework

Since this question seems to be pretty subjective, I'm posting it here.

Let's say you're writing your own version of Stackoverflow using ASP.NET MVC, so there are classes like Question, Answer, User, etc. Since you're lazy, you decided to use entity framework. So, all the classes mentioned above have navigation properties: Question knows its Answers, Answer knows the User who posted it, etc.

You've read a lot of Martin Fowler's books, so for sure you're going to have a service layer to implement all the business logic there. You're going to use ASP.NET MVC only for the UI and application logic related functionality.

There are 2 questions:

  1. Will you directly expose objects of Question, Answer and others to the controllers?
  2. Will you do the same for views?

I'm basically neither going to provide a REST API to my application, nor I'm too conservative to just have any fears like "hey, MY VIEW is aware of what the Question is, I don't know if it's bad or not, I just don't like it!".

I'm especially curious about the case when the Question class has a field like TimePosted and you bind your PostNewQuestion view to that class. I know that in case I'm not binding that field to any control on the page, it won't be posted, so I'll have that field set to null when I got the object on my controller side. Is it considered fine or is it bad idea? 2 opposite approaches I'm thinking of are "using DTOs/ViewModels everywhere" and "wtf, less classes is always better!"

What do you think is a right approach? (I know there's no direct answer, so the question in fact is "what should one consider to decide whether using DTOs/ViewModels/Whatever else is good for its app's architecture?")

Also please note we're considering a very simplified clone of Stackoverflow, so:

  1. It's a web-only project (we're not going to expose REST API or whatever else)
  2. There are users, questions, answers, tags and search functionality (no outstanding business logic)
  3. There are like 100 active users per day (no special performance requirements)
  4. The code should be readable and there should be no surprises or places of special interest in case a new member joins the dev team.

You may also express your thoughts in case any of first 3 points get changed – "the customer now wants our service to allow 10000 simultaneous users" or "we now need to only allow every single user to post once per 15 minutes", etc.

Thanks!

Best Answer

I haven't worked much with MVC, however I have worked a lot with MVVM and here's my take on it:

Question, Answer, and User are all data objects. Its OK for them to know of each other, but they should not be aware of anything outside of the data object layer, such as Views, Controllers, ViewModels, etc.

In an ideal world, your View only references the Models. They might know of the Controller, but they shouldn't have to reference it directly. The ViewModel only knows of other Models. The Controller knows about Models and ViewModels. It doesn't care about the View at all, even though it supplies the View with ViewModels or Models.

So your objects end up looking like this:

  • M odels come in two varieties: Models and ViewModels.

    • Models are simple data objects that simply exist to hold data, and are generally a reflection of database data. They do not access the database or contain any sort of business logic that is unrelated to them.
    • ViewModels are data objects that contain data that the View needs, not necessarily what the database needs. They can contain Models, although Models should not contain ViewModels.
  • C ontrollers contain your business logic. They control the data access calls, creating Models/ViewModels to pass to the View, advanced business logic such as permissions, etc. They basically control the entire code layer.

  • V iews are just used to give the users a user-friendly interface. They accept either a ViewModel or Model, and display it in some way that looks nice to the user.