views:

913

answers:

5

I am setting up an n-tier application with MVC, Ninject, and NHibernate (my first using these technologies). For clarity's sake, the tiers are a "Data" tier, a "Services" tier, and a "Web" tier (all are separate projects).

With MVC, you have your models that are in the "Models" folder. It seems necessary to put my models here to create strongly-typed Views and to generally keep with the philosophy of MVC.

However, with NHibernate, I also need my models in the "Data" tier so that the mapping can take place and that NHibernate can instantiate actual objects to return to the services layer.

Duplicating the classes across projects is not very DRY and abstracting them into their own library doesn't seem to play well with MVC (neither in practice nor philosophy).

Any thoughts? How do you structure your O/RM objects vs MVC models?

+4  A: 

I keep Entity Framework models/classes in the data tier and use the Models folder of the MVC project for presentation models and model binders.

Craig Stuntz
Okay. So it seems like the consensus is to keep Presentation Models in the Web tier and my Domain Models in the Data tier. So what should my Services tier return to the Web tier? Should it know about the Presentation Models? Or should it return Domain Models?
Jeffaxe
No, I don't think the services should know about presentation models. Indeed, there's probably no way a service could know about every possible presentation model needed. The service should return transfer objects, which could be entity types. The web tier can make that into a presentation model.
Craig Stuntz
That makes sense. Still, though, this mapping of Domain Models to Presentation Models doesn't seem very DRY, especially when the two Models will be similar.
Jeffaxe
They're not the same. Consider: PM is optimized for data binding and user language. It lives by itself on the view/action. DM is optimized for compatibility with the rest of the domain. LINQ transforms them easily.
Craig Stuntz
That said, for cases where they *happen* to be the same, you can pass the DM through to the view.
Craig Stuntz
+1 This sucks but it's the right way to go. In the RoR world, we generally have one single model (not two), and things get messy fast.
Yar
+4  A: 

I keep all of my models in the data tier because of NHibernate. Take a look at S#arp Architecture for a great way of keeping your presentation clean. Models do not have to be physically located in your web project for your views to be strongly typed.

Chris Conway
+4  A: 

The Data Model is it's own thing. The Model in MVC is something different. It's the model of what you're going to display, which may or may not be your Data Model. You're Data Model may transcend layers, or not.
Take for instance the standard sign-up form. The Data Model may include the username, password and an array of login history classes, a flag indicating it's active and much other stuff. The model in MVC, may only really care about username and password, and that the user type the password twice. Does your Data Model really need two password fields? No. However the model in the MVC does. Hence, two different critters.

Jim Barrows
Okay. So it seems like the consensus is to keep Presentation Models in the Web tier and my Domain Models in the Data tier. So what should my Services tier return to the Web tier? Should it know about the Presentation Models? Or should it return Domain Models?
Jeffaxe
The services tier should return the data model. Or, ask yourself.. what happens if I have different interface accessing my services? The less your service tier knows about the front end, the better off you'll be in the long run.
Jim Barrows
A: 

With MVC, you have your models that are in the "Models" folder. It seems necessary to put my models here to create strongly-typed Views and to generally keep with the philosophy of MVC.

No model can be anything you want. I would still use a presentation model if it were necessary but I have no objection to using your nhibernate entities in your views.

With NHibernate you don't really need a Data Tier since the Session itself is the data tier.

The service tier seems like a valid idea but only if you plan on having multiple client for this layer.

Otherwise, I would only have 1 project and use namespaces to separate my layers. It builds faster and is easier to deploy.

Simon Laroche
"With NHibernate you don't really need a Data Tier since the Session itself is the data tier."To implement the Repository pattern, I am abstracting the Data tier. That way, my services are programmed against an interface and the Data tier is easily interchangeable (i.e. switching O/RM's).
Jeffaxe
You could then put your entities in a core library and put your repositories with your services then. Repositories are services.
Simon Laroche
+1  A: 

You are right about the DRY principle here. I keep my LINQ-to-SQL objects separated from my business objects and I have some duplication and it doesn't make me feel good but it seems there isn't a simple workaround this..

I had a tough time making this decision but I watched Rob Conery's blog while building the MVC Storefront and in the end I decided to go this way (ORM objects AND business objects)

Andrei Rinea