views:

66

answers:

1

I've been using ASP.net MVC for about two years now and I'm still learning the best way to structure an application.

I wanted to throw out these ideas that I've gathered and see if they are "acceptable" ways in the community to design MVC applications.

Here is my basic layout:

  • DataAccess Project - Contains all repository classes, LINQ-to-SQL data contexts, Filters, and custom business objects for non-MS SQL db repositories (that LINQ-to-SQL doesn't create). The repositories typically only have basic CRUD for the object they're managing.

  • Service Project - Contains service classes that perform business logic. They take orders from the Controllers and tell the repositories what to do.

  • UI Project - Contains view models and some wrappers around things like the ConfigurationManager (for unit testing).

  • Main MVC Project - Contains controllers and views, along with javascript and css.

Does this seem like a good way to structure ASP.NET MVC 2 applications? Any other ideas or suggestions?

Are view models used for all output to views and input from views?

I'm leaning down the path of making view models for each business object that needs to display data in the view and making them basic classes with a bunch of properties that are all strings. This makes dealing with the views pretty easy. The service layer then needs to manage mapping properties from the view model to the business object. This is a source of some of my confusion because most of the examples I've seen on MVC/MVC2 do not use a view model unless you need something like a combo box.

If you use MVC 2's new model validation, would you then validate the viewmodel object and not have to worry about putting the validation attributes on the business objects?

How do you unit test this type of validation or should I not unit test that validation messages are returned?

Thanks!

+2  A: 

Interesting.

One thing I do differently is that I split off my DataAccess project from my Domain project. The domain project still contains all the interfaces for my repositories but my DataAccess project contains all the concrete implementations of them.

You don't want stuff like DataContext leaking into your domain project. Following the onion architecture your domain shouldn't have any dependencies on external infrastructure... I would consider DataAccess to have that because it's directly tied to a database.

Splitting them off means that my domain doesn't have a dependency on any ORM or database, so I can swap them out easily if need be.

Cheers,
Charles

Ps. What does your project dependency look like? I've been wondering where to put my ViewModels. Maybe a separate UI project is a good idea, but I'm not entirely sure how that would work. How do they flow through the different project tiers of your application?

Charlino
Jead reading your comments and it sounds like you can't do this with Linq to SQL, which is true. I would definately look at using NHibernate or EntityFramework CodeFirst. EF CodeFirst is actually pretty cool... I'm using it with an existing schema and I've only run into one issue, but that was more to do with how (stupidly) the database was designed.
Charlino
@Charlino: The project dependency is something like this: Main MVC project depends on DataAccess, Service and UI; DataAccess depends on nothing(other than linq/ef framework stuff); Service depends on DataAccess and UI projects; and UI depends on nothing. As I said, I do have some wrapper classes in the UI which makes me add a dependency to MVC framework. I've been debating whether to move those classes into the MVC project to remove this dependency. Then, the UI would only hold the plain view model classes.
Dragn1821
@Charlino: Currently, I'm thinking about using the view models to accept all input or to display output at the view level. Then, the controller would pass the view model to the service layer where the view model would be mapped over to the ORM class that LINQ-to-SQL creates before the ORM class is passed into the repository. Or, the ORM class is read from the repository and mapped over to the view model class which is returned from the service layer through the controller and to the view. So, the service layer would do all the heavy lifting. Does this sound like a good approach?
Dragn1821
Sounds like a good approach. It's basically the same flow as what I've got, except I've split it between only 3 projects (Domain, DataAccess, WebSite). WebSite and DataAceess are obvious. The Domain project contains all my view models, services and repository interfaces. It works well and I can't see any benefit of splitting them any further. I was thinking about moving the view models out because some MVC stuff is creeping in. Not entirely sure how to do that seeings my services need them as a parameter. I might just try extending them in the WebSite application to include MVC specific stuff.
Charlino
After looking into the Onion Architecture, I'm liking how that completely decouples your application from technologies that can change. I'm still trying to wrap my head around it, but I did find this video that helped me out a bit more than just the artical posted above: http://www.screencast.com/users/HeadspringSystems/folders/Community/media/828f0914-26ff-4b98-91a0-cf298abcab0a
Dragn1821