Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

This is more of a "how would you do it" type of question.

The application I'm working on is an ASP.NET MVC4 app using Razor syntax.

I've got a nice domain model which has a few polymorphic classes, awesome to work with in the code, but I have a few questions regarding the MVC front-end.

Views are easy to build for normal classes, but when it comes to the polymorphic ones I'm stuck on deciding how to implement them.

The one (ugly) option is to build a page which handles the base type (eg. IContract) and has a bunch of if statements to check if we passed in a IServiceContract or ISupplyContract instance. Not pretty and very nasty to maintain.

The other option is to build a view for each of these IContract child classes, breaking DRY principles completely. Don't like doing this for obvious reasons.

Another option (also not great) is to split the view into chunks with partials and build partial views for each of the child types that are loaded into the main view for the base type, then deciding to show or hide the partial in a single if statement in the partial. Also messy.

I've also been thinking about building a master page with sections for the fields that only occur in subclasses and to build views for each subclass referencing the master page. This looks like the least problematic solution? It will allow for fairly simple maintenance and it doesn't involve code duplication.

What are your thoughts? Am I missing something obvious that will make our lives easier? Suggestions?

share|improve this question
8  
Do Not make your presentation layer depend on your domain design. –  Lisa Sep 13 '12 at 6:20
    
It all depends: How many differences and how common those classes and expected views are? I wouldn't mind creating different views if the domain classes didn't have much in common. –  Euphoric Sep 13 '12 at 16:04
add comment

migrated from stackoverflow.com Sep 13 '12 at 13:40

This question came from our site for professional and enthusiast programmers.

3 Answers

Actually, building individual views for each of the IContract classes would not be breaking DRY -- presumably they have some different info with different needs. You aren't repeating yourself, you are successfully using polymorphisim.

I had a somewhat similar conoundrum for a project MVC1 project -- before DisplayFor provided a pretty good built-in solution. We used MVC Contrib's RenderAction delegates to send the polymorphic object off to a specialized controller that was responsible for dispatching things to the appropriate rendering pipeline. The internals get a bit squirrely, but it has been a rock solid system for us for 3 years or more.

share|improve this answer
    
There would be quite a bit of repeating markup code in the views. Better to use partials for the functionality that's specific to each subclass. –  Nik Sep 13 '12 at 18:08
1  
That is exactly what we were doing -- rendering partial views for each subclass. Also, I've seen a few attempts at getting a bit too DRY in view code -- lots of fun with weird cross-cutting dependencies that are impossible to test. –  Wyatt Barnett Sep 13 '12 at 18:40
    
I agree. DRY is always somewhat in conflict with both Liskov substitution principle and Law of Demeter. And, of the three, DRY is the most dispensable. Don't let DRY get in the way of overall good architecture. If there are ways to remove the duplication (such as extracting parts and reusing via composition), those will shake out over time. –  Amy Blankenship Mar 12 '13 at 22:49
add comment

The solution we've used - where this is appropriate - is to use DisplayFor and EditFor

We have strongly typed display and edit templates so the base view is a nice, simple, clean iteration over a list of items and the templates handle the polymorphism.

One can argue about the suitability of building views over domain models - but that doesn't remove the requirement to be able to display a list of items that have are notionally the same (have a common root) but vary in detail and in the case we have this solved the problem very neatly without having to put any logic in the view

share|improve this answer
add comment

I think your most practical option is just to check what flavor of IContract you're dealing with and then extract the custom markup into partials that contain the markup that's specific to that model object. This way your main view handles the generic IContract markup output and the partials have the custom WhateverContract details.

I would only write separate full views if the objects were so different as to where there would be little or no markup repetition. Its better to have a few if/elses in your main view than having to update multiple views when you need to make a change.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.