maandag 11 mei 2009

Isolating the domain model from your view

When working with the ASP.NET MVC framework I have a strong urge to not pass my domain models directly to the view (and I feel that’s a good thing). Actually, I should refine that. I do not pass my domain models to the view as a domain class. Let’s investigate.

My model at the moment consists of a class called Contact. It’s very simple:

	public class Contact
public int Id { get; set; }
public string LastName { get; set; }

This class is populated with data from my datasource (a static List<Contact> for now), and later on it’ll be used in my domain logic. For now it’s a simple data class. Now, for a view which is used to edit this entity, the first idea is to go with a strongly typed viewdata, like such:

<%@ Page Title="" 
Inherits="ViewPage<Contact>" %>

Basically I’m passing the domain model directly into the view. Not really a good thing in my opinion, because I’m exposing waaay too much of the model to the view. I only need a few simple getters, and perhaps some combined getters (in case of a person, one which appends first/lastname for instance). The solution I use for this is to wrap the domain model in a viewdata class, without exposing the actual model itself.

	public class ViewContact
private readonly Contact contact;

public ViewContact(Contact contact)
{ = contact;

public int Id { get { return contact.Id; } }

public string DisplayName
get { return contact.LastName; }

As you can see, the actual model is passed in as a parameter to the constructor, but I’m not exposing it directly. What I can do now is pass this object to the view, without exposing the model:


Page Title=""



Inherits="ViewPage<ViewContact>" %>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

    <h2>Editing: [<%= Model.Id %>] <%= Model.DisplayName %></h2>

    <% using (Html.BeginForm("Update", "Contact")){ %>



    <% } %>


Now I’ve got a simple way to isolate my domain model from my view, by using a wrapper class. This way I can explicitly specify what I want to be able to use in my views, without having to conform my domain model to that. I can have a rich domain model, while still limiting the amount of information I get in my view. I’m not sure how this will work out, so I’ll probably follow up on this blog with new insights, or perhaps a complete abandoning of the pattern later ;-)

1 opmerking:

Matt Hinze zei

Instead of hand-coding all that repetitive wrapper code you can use the excellent AutoMapper tool to do it automatically.