4

I'm trying to understand the best architecture for my MVC2 site.

As I have been experimenting with getting the data in and out of a database with Entity Framework, I am beginning to realize the simple domain-models I have so far constructed do not map to all the needs of my planned views. So I am considering following the accpepted answer to this question: Why Two Classes, View Model and Domain Model?.

But there seems to be redundancy with little payoff that I can perceive between the domain-models and the EF models, and I can't even hardly understand the conceptual difference. I do NOT have as a requirement the need to switch data sources down the road, and I do not forsee the need to switch my ORM solution either.

QUESTION:
If I follow this pattern then, since I am using Entity Framework, shouldn't I just use my EF entities to serve directly as the domain models? (note: I haven't thought through the "how" of that, but answers there are welcome too.) Or am I still advised to manage a separate set of domain-models?

Community
  • 1
  • 1
Faust
  • 15,130
  • 9
  • 54
  • 111
  • Just to clarify: You're currently using your EF Classes as your domain model right? You haven't created duplicate classes as a domain model? – Yngve B-Nilsen Apr 15 '11 at 11:32
  • Well, yes I have (and it seems so redundant, hence the question) but so far just on one entity as a test to see how to get everything vertically integrated through the layers from the controller to the data store for basic crud operations. I take it you'd agree that that's entirely unnecessary. My challenge has been learning from a book (Pro ASP.Net MVC2 Framework) that covers Linq2SQL only (not EF), and filling in the missing pieces from various articles on the web. – Faust Apr 15 '11 at 12:45
  • does my answer help any? – Yngve B-Nilsen Apr 15 '11 at 12:52
  • @Yngve: yes, please see comment below it. – Faust Apr 15 '11 at 13:09
  • Yup, there you go. Updated my answer :) – Yngve B-Nilsen Apr 15 '11 at 14:29

1 Answers1

7

It seems you've got some redundancy here. Reading your paragraph:

But there seems to be redundancy with little payoff that I can perceive between the domain-models and the EF models, and I can't even hardly understand the conceptual difference.

I would argue that there is no real difference between the EF Model and your Domain Model. In the projects I create, my EF Model is my Domain model.

However, my Domain model classes are not the same as my ViewModels. The Domain model class might contain data that is not interesting for the View, or maybe the view needs information that is calculated/evaluated based on information in view. A simple example might be:

public class Session // Domain model (and EF Model
{
    public int Id {get; set; }
    public DateTime Start {get; set; }
    public int DurationInMinutes {get; set; }

}

public class SessionViewModel // The viewmodel :p
{
   public DateTime Start {get; set; }
   public int DurationInMinutes {get; set;}
   public DateTime End 
   {
       get
       {
            return Start.Add(TimeSpan.FromMinutes(DurationInMinutes));
       }
   }
}

In this example I'm interested in displaying the actual End-time in my View, but I have no interest in storing it in the database, as that might lead to data-discrepencies (DurationInMinutes + Start might not equal End if data is corrupted upon saving)

When I first started coding this way, I ended up doing alot of manual work mapping my Domain models to ViewModels, and back. AutoMapper changed all that :) Google it, or NuGet it and it will make your life a whole lot easier :)

Hope this helps a little. Please comment if I'm totally missing the point :)

Update to address the comment

DataAnnotations would then be applied to the ViewModel, because normally DataAnnotations denote how the data should be displayed and validated in the View.

For instance you would put the [Required] attribute on public DateTime Start {get; set;} in order for the Html.DisplayFor extensions automatically validates your HTML according to your dataannotations.

By definition (by some anyway) the Domain Model should not contain any code or logic related to your business logic. The Domain Model is simply responsible for containing the data pretty raw according to your datastore. Personally I like to put some sort of Service layer inbetween that is responsible for fetching the data and returning ViewModels, and also doing the reverse.

The ultimate goal is to avoid referencing your domainmodel directly from your controllers.

Of course, all these points has to be weighed in reference to the size of the project. It's certainly overkill to do all this just to mock up a test-site - but in any other project where you'll actually be deploying something that might scale, expand or otherwise change, it's a good practice to get used to, as it seriously increases your ability to do so.

Another key point to this approach is that you are forced to abstract your operations down to smaller and more managable units, enabling better and more precise unit-tests.

Daniel Liuzzi
  • 16,807
  • 8
  • 52
  • 57
Yngve B-Nilsen
  • 9,606
  • 2
  • 36
  • 50
  • You're definitely addressing my question. A related question: How do you, then, apply data annotations on the domain-models? Are you going into the EF model.Designer.cs file and adding code in there? In my referece book, which only covers MVC2 with Linq2SQL, annotations are applied to the hand-coded domain models. – Faust Apr 15 '11 at 12:56
  • OK, things are getting clearer (I think). So, what I was thinking as a domain model is probably better thought of as a viewmodel, which happens to mirror my entity (domain model) because I'm only tackling CRUD operations a the moment. I can accept that. I've gotten Automapper to work rather well in the repository (service layer?), and that looks to be very useful for creating a generic repository to support these basic CRUD operations for all my entity types. Does it sound like I'm on the right track with that? – Faust Apr 15 '11 at 14:58
  • Yeah, it seems like you're on the right track! I would stick with the terminology that you describe here - View model as the first, domain model as the Entity model. Repository/Service layer really depends on what it's actually doing, and if you're not sure if it really is a repository layer, call it a Service layer :) Stick to those names, and it will be much easier to ask good questions here on StackOverflow as your project grows larger :) – Yngve B-Nilsen Apr 15 '11 at 15:31
  • I've been going through a pretty serious brain dump on DDD just lately and trying to get it working with EF without introducing an enormous amount of complexity (DTOs on top of DTOs, etc). Your answer here was helpful, but I was confused by what you said about the domain model not containing any business logic. That would be an anemic data model, right? I guess this must be one of the areas people are debating. Very confusing trying to get into this with so many opinions floating around. – Brian MacKay Jan 30 '13 at 00:23
  • @BrianMacKay Since this answer I've been doing work in terms of Domain Models and in particulary the repo-pattern. The way I end up doing things are by keeping an aggregate root, let's say a User. If I need to change a password for that user, that's a method with logic for password-changing on the User-class. If I need to change child-objects for that User, that will also be methods on the User, passing calls down the stack. But business logic in terms of how the system should work are kept in f.i. commands (CQRSish). It's a big discussion, but in the end it all comes down what fits you:) – Yngve B-Nilsen Jan 30 '13 at 16:26
  • Frustratingly, after spending countless hours researching DDD, it looks like I'm ending up back an an n-tier architecture and just evolving my approach... I was hoping to find a way to do something more model driven with the middle layers, possibly adapting parts of DDD to the smaller scale that I tend to work at, but I'm not seeing good ways to do it that wouldn't increase the complexity by a bewildering degree. It's dissapointing becuase the projects I work on do need good architecture even though it's not a 50 man team. – Brian MacKay Jan 30 '13 at 19:11
  • That said, the guidance about using the EF model as the domain model was helpful. Most things I saw seemed to indicate that you should have a seperate model and a parade of DTOs. ;) – Brian MacKay Jan 30 '13 at 19:14