About the book
This is the second chapter
of the book ASP.NET MVC in Action. It has been
published with the exclusive permission of Manning.
Written by: Jeffrey Palermo, Ben Scheirman, and Jimmy
Bogard
Pages: 392
Publisher: ManningISBN-10:
1933988622
ISBN-13: 978-1933988627
Get 30% discount
DotNetSlacker readers can get 30% off the full print book or ebook at www.manning.com using the promo code
dns30 at checkout.
Introduction
Without a model, software is not interesting. A model in the English language is just like a model in software: a representation of
the real thing. In software, we represent the real world by using objects that are named after concepts we deal with every day. These
objects have attributes and behaviors similar to those found in the real world. In this chapter, we'll explore a model for a system that
helps to manage a small conference, like a Code Camp. The model enables the application to provide an interesting service. Without the
model, the application provides no value. We place great importance on creating a rich model with which our controllers can work.
The style of modeling we'll use in this book is domain-driven design (DDD), as conveyed by Eric Evans in his book, Domain-Driven
Design: Tackling Complexity in the Heart of Software. Covering the topic in depth is a book in itself; we'll tackle a small primer,
which should enable you to follow the software examples in the rest of this book. After the DDD primer, we'll discuss how to best use
the domain model; then we'll move through how to use a presentation model to keep controllers and views simple. We'll keep a keen eye on
SoC, and we'll ensure that every class has a single, well-defined responsibility. Before digging deep, we need a good understanding of
the basics of DDD.
Understanding the basics of domain-driven design
Developers can use different methods to model software. The method we prefer is domain-driven design, which looks at the business
domain targeted by the software and models objects to represent the appropriate concepts. We refer to the domain model as the object
graph that represents the business domain of the software. If the software lives in the online e-commerce space, we would expect to find
objects such as Order, Customer, Product, etc. These are not just data-transfer objects either. They are rich objects with properties
and methods that mimic behavior in that business space. Popular in .NET development, the DataSet object would not be appropriate in a
domain model because the DataSet is a relational representation of database tables. Whereas the DataSet is a model focused on the data
relationships and persistence, a domain model is focused more on behavior and responsibility. In our fictitious e-commerce application,
when retrieving order history for a customer, we would want to retrieve an array or collection of Order objects, not a DataSet of order
data. The heavy focus on the demarcation of behavior and the encapsulated view of data is key in DDD. If you are unfamiliar with
domain-driven design, you may want to review some of the following references. Reviewing these publications is not necessary for the
purpose of this book, but they will help you as you develop software in your career. From this point forward we'll defer to these
resources for more detail on domain models, aggregates, aggregate roots, repositories, entities, and value objects. When discussing each
of these concepts, we'll talk only briefly about their purpose and then move on. The next section is an overview of the core domain
model for this book.
References for learning moreDomain-Driven Design: Tackling Complexity in the Heart of Software by Eric Evans - The
most complete reference for DDD. Evans can be credited for making this collection of patterns known. He applies his own experience as he
names patterns that work together to simplify complex software. Addison-Wesley Professional (2003).
Domain Driven Design Quickly
by Abel Avram Floyd Marinescu - A 104-page book designed to be a more concise guide to DDD than Evans' book. This e-book is summarized
mainly from Evans' book. Lulu Press, Inc. (2007).
Applying Domain-Driven Design and Patterns: With Examples in C# and .NET by
Jimmy Nilsson - The author takes the reader through real, complete examples and applies DDD patterns along with test-driven development
(TDD) and O/R mapping. Addison Wesley Professional (2006).
http://domaindrivendesign.org/-An evolving, information website maintained by Eric Evans, Jimmy Nilsson, and Ying
Hu.
Domain model for this book
Throughout the rest of this book, our examples will be centered on the open source project, CodeCampServer. Authors of this book
started the project, and it is being extended at the time of publishing by a strong network of contributors. This software can serve as
the official website for a software conference, often called a Code Camp. The domain model is centered on the concepts present when
managing a Code Camp. Since Code Camp is a common name (also common is TechFest or BarCamp), our central object is Conference. In figure
1, you see the complete domain model for the application, and we'll work with different pieces in the examples following in the chapter
and the rest of the book.
Figure 1: Partial domain model for CodeCampServer, which will serve as the basis of future examples in this book.

Key entities and value objects
Figure 1 shows some of the entities and value objects in play within our domain model. The entities are the key objects in our
domain model, such as Conference, Session, Track, and TimeSlot. With so many types in the diagram, you probably wonder what is special
about these classes and what makes them entities. The reason these are entities is that they have the concept of an identity, a property
which can be examined to determine uniqueness. The reason we give these objects an identifier is that these can stand on their own, and
we can speak about these objects without other supporting concepts. It would make sense to list a collection of any of these objects.
Entities can stand on their own, and we can reason about them in a collection or as a single object.
Value objects don't make
sense on their own without the supporting context of an entity to which they belong. Two value objects in our domain model are Session
Level and Conference Address. Also many properties of entities are value objects. Let's discuss Level and what context is required for
it to make any sense.
A Level has a value that indicates the difficulty level of the session. It does not have an identifier.
Level belongs completely to the Session class. Without Session, Level would have no context and would have no meaning. The purpose of
Level is to denote the information that helps attendees of the conference choose what sessions may be appropriate. Being a value object,
Level is defined by its properties and methods and has no identifier. It would not make sense to list out a collection or array of Level
instances because without the Session, it has no meaning or purpose. Its relationship with other entities gives it meaning. The Session
it belongs to and the difficulty level information it includes give it the context to convey meaning in the application, and when some
other code needs the session's Level, it must ask the Session instance for the Level. The Session object will hand back this object.
Like Level, other types without identifiers are value objects. Value objects are not glamorous and even describing them can be boring.
The arrangement of entities and value objects into larger structures can be interesting.
Entities and value objects are useful in
separating responsibilities in a domain model, but there is more. If we need to load a Conference entity for the Austin .NET User Group
Code Camp, what does that mean? We see that our Conference object can have many Sessions, and that each Session has a Speaker. Going
further, a Speaker has a WebsiteUrl property. Tracks, Sessions, and Attendees all have a relationship with a Conference.
When we need to deal with a Conference object, must we have all associated objects in memory for any operation to make sense? The answer
is no. In DDD, we divide our domain model into aggregates.
Aggregates
Aggregates are groups of objects that work and live together. We group them along natural operational lines, and one entity serves as
the aggregate root. The aggregate root serves as the entry point and the hub of operations for all objects in the aggregate. An
aggregate can have many objects, or it can just be a single entity, but the aggregate root is always an entity since it must be able to
stand on its own, and only entities can stand on their own. In figure 2, we see some of the aggregates for CodeCampServer, with the
Conference aggregate in the center.
The aggregate root is the Conference class, and another member of the Conference aggregate is
Attendee. This is not the complete Conference aggregate, but it demonstrates some conventions of the aggregate pattern. It may seem
trivial that we classify this object in the Conference aggregate, but specifying ownership is valuable.
Figure 2: The conference aggregate

We have specified that the Conference type owns the types in the Conference aggregate. Objects in
other aggregates are not allowed to have a durable relationship with the nonroot objects in the Conference aggregate.
NOTESession holds a reference to Track, which is another aggregate root. Types in an aggregate are allowed to hold
references to other aggregate roots only, not to other nonroot types in a different aggregate. For instance, even if only five
Attendees could attend a session, Session would not be allowed to have a reference to the several Attendee instances because Attendee
is a nonroot type in the Conference aggregate. In short, if a type belongs to an aggregate, types in other aggregates must not hold a
durable reference.
The separation into aggregates enables the application to work with domain objects easily. If we did not draw aggregate
boundaries, the entire domain model could easily devolve into a ball of spaghetti references. Conceivably, we wouldn't be able to use
any objects without the entire object graph loaded into memory. Aggregate boundaries help us to define how much of the domain model is
necessary for an interesting operation. For instance, if we want to show conference information on a screen with the location,
directions, sessions, and speakers, we don't need to load the entire object graph. We only need the Conference aggregate and the other
aggregate roots that are necessary. In fact, if we need only the start and end dates for the conference, we would not even have to load
the entire Conference aggregate. Now that we are discussing how much of the object graph to load, you might wonder why we haven't yet
discussed persistence to a database.
Persistence for the domain model
For this book, persistence is just not that interesting. Sure, we can imagine how we might load and save these objects from and to a
relational database, xml files, web services, and so on, but when designing a domain model, persistence concerns are mostly orthogonal
to the model. For most business applications, we'll have to durably save the state of the application somehow, but the domain model
should not have to care whether that persistence is to XML files, a relational database, an object database, or if the entire state of
the application is just kept around in memory
NOTEPersistence is interesting and necessary for real applications. We are not discussing specific data access
techniques because that topic is orthogonal to the ASP.NET MVC Framework. The MVC framework is a presentation layer concern, and it can
work with many data access strategies. Your back-end data access decisions do not change if you use the ASP.NET MVC Framework instead of
Web Forms, Windows Forms, WPF, Silverlight, or even a console UI.
Regardless of the persistence mechanism, the domain model includes a concept for loading and saving object state. Notice how
we are not talking about loading and saving data. In the domain model, we are concerned about objects, not data. We need to load object
state and persist object state. We do that using repository types. In domain driven design, we dedicate a repository to each aggregate,
and the repository is responsible for loading and saving object state. The repository performs the operations on the aggregate root
only. In the case of the Conference aggregate, we'll work with a type called IConferenceRepository. In figure 3, we see the repository
whose responsibility it is to perform persistence operations on the Conference aggregate. For more examples, we have a repository for
each aggregate in our domain model. Some of them are listed here:
IConferenceRepository - Persistence operations on the Conference aggregate
ISessionRepository - Persistence operations on the Session aggregate
ITimeSlotRepository - Persistence operations on the TimeSlot aggregate
ITrackRepository - Persistence operations on the Session Track aggregate
Figure 3: IConferenceRepository-all persistence operations on the aggregate root

Let's
examine the Conference aggregate once again as it relates to persistence. Suppose that when managing a Code Camp with this application
we add several attendees. In the application we would add Attendee instances to our Conference instance and then pass our Conference to
the Save() method of IConferenceRepository. The repository would be responsible for saving the Attendee instances as well
because these objects live within the Conference aggregate. The repository's responsibility is to manage persistence for the Conference
aggregate, which means every object in the aggregate.
You are probably wondering what mechanism we are using for persistence
because we still have not mentioned it. With this book, you can download the full source code and examine the classes that implement our
repository interfaces, but for the purpose of exploring the ASP.NET MVC Framework, we find it irrelevant and a distraction to explore
the data access code, and we'll keep this book's focus on the presentation layer, which is where the ASP.NET MVC Framework lives. The
repository interfaces will provide the objects we need to work with for all the examples in this book, and the controller classes will
depend on these repository interfaces as well as other logical service types. Since data access and a screen controller have completely
different concerns, a screen controller in this book will never concern itself with how any sort of data access is performed, or that
data access is happening at all. A screen controller will call methods on dependencies, which will often be repositories, and when
calling the Save() method on IConferenceRepository, the screen controller does not care whether the implementation saves
the object in an in-memory cache, an XML file, or a relational database. The controller will merely call the repository and trust that
what is behind the interface will work appropriately.
NOTENo doubt you have seen some examples where controller actions directly contain data access code. With LINQ to SQL
being new and growing in popularity, conference talks are featuring ASP.NET MVC Framework demos where a controller action performs a
LINQ to SQL query. This works for small or short-lived applications, but it is inappropriate for long-lived business applications
because of the coupling. For years, the industry has known that coupling presentation concerns with data access concerns is a recipe for
disaster. These concepts gave birth to the well-known data access layer. When using the ASP.NET MVC Framework, a controller is part of
the presentation layer. The best practice still stands to avoid putting data access in your presentation layer; any data access concern
in a controller action creates technical debt that will put a tax on maintenance for the life of the application.
One benefit that we can capitalize on immediately when separating our data access layer from the presentation and business
layers is unit testing. While unit testing our screen controllers, you will notice we frequently fake out the repository interfaces so
that they return a canned list of objects as the context for a test. Unit testing controllers should never involve any persistence
mechanism or exercise external dependencies. We'll cover the unit testing of controllers in much more detail in chapter 3, but in a unit
test, the repository implementation will never come into play. A substitute object will always be provided for the interface. At this
point, we have enough information about our domain model to proceed, but the domain model is not the only type of model that we need.
The domain model is important because it represents unique concepts in the real world. A conference can have many attendees, so that is
how we model it. An attendee describes a person who is coming to the conference, and that is how we represent it in code. Now, what
about a schedule listing? When listing the time slots, sessions, and speakers, how do we work with that in the presentation layer (in
our screens)?
Presentation model
The domain model represents concepts as they truly are, but often a screen in our application needs a transformed representation of
the domain model. For displaying a schedule of a conference, we need a flattened, or projected, model. This is the presentation model, a
model that exists only for specific presentation needs. In the case of a schedule, we'll need to show the start time, end time, title,
and speaker for every session. We can easily ask the repositories for the objects fully populated, and then we have all objects we need.
However, if we place the responsibility on the screen controller for navigating the object graph and pulling all the appropriate pieces
out, we are muddying the responsibilities of the controller. If the application is sufficiently trivial, we may let the controller take
care of this, but that would be a judgment call for you to make. In CodeCampServer, our controllers will be quite thin. The controller
is responsible for coordinating dependencies and forwarding objects for display on to the view. Controller code is code that is coupled
to the framework being used for the UI. We want to get away from framework code as quickly as possible. Whose responsibility, then, is
it to filter and arrange the conference schedule so it is in a shape suitable for display?
Presentation model responsibilities
This is where the presentation model shows its value. The presentation model is responsible for transforming the domain model into a
representation that is useful for the presentation layer, namely, the controller and view. Whereas the domain model is an n-dimension
object graph that accurately represents the real world, the presentation model takes these objects and projects them into a flatter
model that can easily be represented on a graphical screen.
NOTEThe presentation model can be many things. Ultimately, it is an object model that serves a particular screen, not
the entire domain. This object model can be populated in isolation, or it can take responsibility to populate itself when a domain
object is passed into the constructor. The presentation model goes in the /Models folder in an ASP.NET MVC Framework application. The
presentation model is part of the presentation layer and should not be referenced by the rest of the application. Typically a complex
screen will require a presentation model object graph.
Let's revisit our conference listing example. It would not be appropriate for a controller to pass a Conference object to the
view and hope the view knows how to traverse the object graphic in order to render the correct information. This is too much
responsibility for the view. The controller needs an object that it can send to the view so that there is only one way for the view to
render the object or structure of objects. If the view has a decision to make, we have introduced the possibility for a functional bug
in the part of the code that is the most difficult to test. We want to pull all decisions back into the heart of the application where
they can easily be tested. For this, we'll have ScheduleController use a new object in the presentation model called ScheduleForm. The
controller will map a conference into a ScheduleForm instance by leveraging IScheduleMapper. See figure 4 for the ScheduleForm
structure.
The ScheduleForm class, along with header information, can provide us with a collection of TimeSlotAssignmentForm
objects, each of which are presentation objects and are easy to render. ScheduleForm also has a collection of TrackForm objects. These
two collections will form the two axes of the table that the view is going to render for the schedule page. The view merely has to
translate the graph of objects into a table. What makes a presentation object easier to render on a screen than a domain object?
Figure 4: The presentation model contains classes specific to a particular screen. Logic that decides how to structure the
domain model for presentation on a screen can be factored into presentation model's classes.

Projecting from the domain model
A presentation object is easier to render than a domain object because it discards the natural depth of a domain model object graph
and provides a flattened, or projected, interface. In our view, we can ask the ScheduleForm for the two collections of objects that are
the headers and rows of the schedule table when rendered to the screen. The presentation model is intentionally structured to naturally
represent the presentation of the information. The goal of the presentation model is to match the view's desired structure closely.
Figure 5 shows what the full structure looks like.
At the session level, SessionForm is not complicated. The SessionForm is
responsible for representing a single cell in the schedule table on the screen. With track on the table header and time along the first
column, sessions will be rendered in the appropriate track and time slot. The SessionForm has the properties that will be rendered so
that the schedule makes sense.
NOTEThe presentation model is not the only type of specialized model we could use. We have service models, storage
models, security models, and messaging models. The common factor among these is that these object models lie at the extremities of the
application and enable the application to interact with the outside world. The presentation model helps the presentation layer, which
interacts with a human user. A messaging model would represent state and behavior necessary for messaging information to other systems
asynchronously. It is conceivable that the UI could even send a message to the domain in a more complex system with large data entry
screens.
The difference in these models is portability. Domain model objects are not portable. They are contained within the
bounded context where they are useful. Presentation model objects are portable from the application layer up to the UI. A messaging
model would be portable for serialization across MSMQ or similar transfer mechanisms. We would not send our domain objects directly in
messages because we would end up coupling other systems to the shape and types of our domain model. Instead, the messaging model (call
it whatever you like) represents the shape necessary to communicate with the external system or application layer.
The presentation model simplifies the domain model for rendering and helps make the numerous decisions that are necessary for
rendering objects. If a controller or view were left with all these decisions, the likelihood of a defect would increase, and the amount
of code in the controller or view would grow, causing maintainability to decrease. The presentation model is a key element of the
presentation layer and should come into play any time a screen needs to work with an object that is not just an object but a deep object
graph. For simple domain objects, or for merely displaying object header information, a presentation model object might not be
necessary, but if you find yourself digging into an object graph in our view, pull back and consider introducing a presentation object.
The unit tests are easy and quick, and the view becomes much simpler.
Figure 5: The full presentation model for the schedule page. Presentation models usually have primitive properties.

Working with the model
Congratulations! You now understand all you need to know to follow the rest of the examples in this book. Although you could study
DDD for years, understanding this small Code Camp domain model is sufficient to master the techniques presented in the following
chapters. Now that we understand the model we'll be working with, let's put it together and use our Code Camp domain model. We'll start
with a user story: “As a community member, I want to navigate to http://codecampserver.org/austincodecamp2008/schedule so that I can
see a schedule of the conference by day, time slots, and track.”
About user storiesUser stories are widely used by teams using Extreme Programming and other Agile methodologies. A
user story is a placeholder for extensive conversation that takes place between the software customer and the software team. It is the
widely accepted practice for a user story to contain a persona (or the type of user) who finds the functionality valuable. The user
story describes what the persona wants to do and why. This format helps to keep the team focused on a task that is beneficial to a
certain kind of user.
Crafting the route
We know from the previous chapter how to create routes that will map a URL to a particular controller and action. In this case, we
are breaking away from the simple {controller}/{action} route in favor of a URL that is obvious and intuitive.
Furthermore, we are using a route API from MvcContrib inside of CodeCampServer. Chapter 5 will cover ASP.NET MVC routes in depth. This
section focuses on how the model can integrate with the routes. The part of the URL, austincodecamp2008, is actually the unique key that
will identify which conference we are dealing with. In other words, for the next Code Camp, the URL might be
http://codecampserver.org/austincodecamp2009/schedule, and so on. Since the first token in the URL is dynamic, we have a fairly
interesting route, but not difficult to craft. The second token, schedule will denote the controller to use for this request. Now that
we have examined each piece of the URL, take note of the entire route added to the RouteTable as shown in listing 1. This code is in the
RouteConfigurator class.
Listing 1: A route that maps the desired URL to the proper controller and action
This route has concerns other than ensuring the ScheduleController is invoked. The {conferenceKey}/{controller}
portion is the most interesting for now. The constraints ensure that only our conference-centric controllers are available after
the conference key. The framework will match the route with the URL and ensure the ScheduleController is executed with the Index
action by default.
Crafting the controller action
We are very confident that the Index method of the ScheduleController will be invoked for this request, but we must
have our controller in place so that we have a place to add the proper code. We'll create a ScheduleController class in
Website/Controllers/ in our solution. We'll then inherit from the Controller base class and create an Index action method. In
CodeCampServer, all controllers have a layer supertype (as defined by Martin Fowler in his book, Patterns of Enterprise Application
Architecture) called SmartController. SmartController derives from Controller. In your own application, you might adopt your own
controller supertype. The shell of the controller class should look similar to listing 2.
Listing 2: The shell of the ScheduleController class
This is the start of our controller class and action that will help display a conference schedule using a view named
Index. We'll be leveraging an IModelBinder instance to bind the conference key from route data to a Conference object. Next we need to
test drive the logic that will map the conference into the presentation model that is appropriate to forward to the view.
Test-driving the feature
Logic in the application needs to have an automated test to verify that it works correctly. TDD is a technique that helps design
loosely coupled, maintainable code while at the same time building up a complete regression suite of automated unit tests. We are going
to test-drive the Index action method for our controller. We have added the action method first because we decided on the name when we
created the route. To test-drive this functionality, you will need to create an NUnit test fixture in your unit test project. In our
project, we'll call it ScheduleControllerTester.cs. Examine the full unit test in listing 3.
Listing 3: Unit test creates mock objects using Rhino Mocks, a .NET mocking library
NOTEThe S method is defined as return MockRepository.GenerateStub<T>
(argumentsForConstructor);. It resides on the base class as a shortcut. Because these examples are part of the larger
CodeCampServer codebase, it will be valuable for you to explore the code included with this book.
It is important to realize that we are setting up a fake object that implements IScheduleMapper. We are passing this stub to
the controller's constructor, and our controller will use it without knowing the difference. It is worth noting that the application
uses an IoC, or inversion of control, container to manage dependencies. This means that we have a custom controller factory use our
IoC container to create the controller complete with whatever dependencies are declared by the constructor. We'll cover controller
factories in greater depth later in chapter 3, but realize that this is a best practice not just for controllers but for C# code in
general. You can see the IoC container usage by opening the full solution delivered with this book. In general, a class should openly
declare dependencies by requiring they be passed in through the constructor.
To complete this test, we call the Index()
method with the Conference object, then assert that the view name and ViewData.Model are correct. We cannot compile at this
point because the constructor we need does not exist. Let's add the constructor, run the test, and it will fail as expected in figure 6.
We'll now move back to our controller class, and write the interesting code until our unit test passes. The resulting controller
code is shown in listing 4.
Listing 4: The complete controller class for showing a conference schedule
Figure 6: Running the unit test with JetBrains ReSharper shows the test failure, which is what we expect at this point.

The Rhino Mocks dynamic mock libraryWhen performing automated testing on code libraries, developers and testers find
it beneficial to simulate dependencies on which the code relies. By substituting a dependency, the code under test can be evaluated
objectively and repeatedly. This technique delivers great results, but the code clutters the readability of the test and the code that
results is bulky. This is where mocking frameworks like Rhino Mocks come in. Rhino Mocks can generate derived classes on the fly. This
includes interface implementations as well as abstract class derivations. These dynamically created classes can return hard-code values
or assert that a particular method is called with specific arguments. You can read more or download at http://www.ayende.com/projects/rhino-mocks.aspx. Oren Eini is
the creator of Rhino Mocks, a vibrant open source project with many contributors.
The new code is the constructor and the guts of the action method. There does not appear to be much code, so can it possibly be
correct? Is that really all the code that's necessary in the controller? Yes! Let's examine what's going on. First, we are saving our
IScheduleMapper in a private field so we can access it later. Remember that we do not care what object is passed into the constructor as
long as it matches the type required. Next, we take the Conference passed into the Index method and use it to ask the IScheduleMapper
instance to "map" it into an array of ScheduleForm objects. Once we are finished, we'll call View() on the Controller
base class passing in our presentation object. This will cause the Index view to be rendered with an array of ScheduleForm objects
stored in the ViewData.Model property. To prove that the code we are writing is correct, let's go back and run our unit
test to ensure it passes, as shown in figure 7.
Figure 7: With the controller fully implemented, the unit test passes, and we can move on.

Now that you have expertly test-driven a controller action, all that's left is to finish off this feature with a
view that takes the presentation object and formats it properly into HTML. In the controller we are creating a ScheduleForm array by
passing in a Conference that the IScheduleMapper will project into the shape necessary to render the screen. Although we won't publish
the full code of the ScheduleMapper class here, it is useful to look at the structure of the ScheduleForm presentation object graph
shown in figure 8. The supporting objects represent the time slots and tracks used to create the visual representation in the view.
Using these objects, the view can easily render the schedule.
Finishing the view
We'll get into all the different ways to use views in chapter 4, but for now, we'll take the simple route and not make use of many
view helpers. You will learn about view helpers later, but for this feature, we'll stick with simple HTML. Following convention, we'll
create an MVC View Page in Website/Views/Schedule/. The rest of the work is just formatting, so we'll format the name of the conference
in big letters at the top of the screen and then show the sessions in a table below. If you are curious about the layout used, browse
through the solution delivered with the book. Examine listing 5 for the full source for View.aspx.
Figure 8: The complete ScheduleForm presentation model nicely encapsulates the presentation concern that would otherwise have
cluttered our controller and view.

Listing 5: A view that formats our presentation object, ScheduleForm, as HTML
Note that we are using <%= operators to output properties of the presentation object. The code in listing
5 is such a mix of server-side code and markup that you might have trouble following it. When we discuss views in depth, we'll introduce
techniques to simplify the view and extract even view logic into helpers. You can imagine what this view would look like if we attempted
to pass the Conference object directly instead of a ScheduleForm object. To get the speaker name, the view would have to traverse three
different object relationships and even perform lookup logic. It would be a mess. The view in listing 5 formats our presentation object
and completes the current feature. If you run the application, you'll see a screen similar to figure 9.
Figure 9: When we run the application, we see our controller and view work as intended. With a well-defined domain model and
presentation model, the controller and view can become quite simple. Test data is used; the session names are not descriptive.

Summary
You have just completed a whirlwind tour of the M in Model-View-Controller. Key takeaways from this chapter are understanding both
the importance of a rich domain model and when a presentation model makes controllers and view simpler. The domain model represents
concepts as they exist in the real world. The names should be the same, the operations (methods) should be the same, and the
relationships should mirror how the concepts are used in reality. With an intelligent domain model, the application has a solid core to
build around.
Left to work with aggregates alone, the controller must take the responsibility for extracting information out of
the object graph for the view to render. This makes the controller more complicated and harder to test. Complexity and difficult
testability both result in more costly maintenance. This is where the presentation model comes in. Use presentation model objects to
project a deep domain object graph into a flattened view that is easy for a view to render. Creating these presentation objects is a
snap for a controller, and when used properly, test-driving controller logic becomes easy and predictable.
With a proper model in
place, the controller and view are straightforward. As you build your applications around the ASP.NET MVC Framework, do not forget the
paramount importance of the model. Model comes first in the pattern name, and it should come first in your application. If you take
shortcuts with the model, the controllers and views are going to be much more difficult to manage. The model is the core of each layer
in the application. If the core is rotten, the entire application will soon smell quite bad.
Get 30% discount
DotNetSlacker readers can get 30% off the full print book or ebook at www.manning.com using the promo code
dns30 at checkout.
About Manning Publications
 |
Manning Publication publishes computer books for professionals--programmers, system administrators, designers, architects, managers and others. Our focus is on computing titles at professional levels. We care about the quality of our books. We work with our authors to coax out of them the best writi...
This author has published 33 articles on DotNetSlackers. View other articles or the complete profile here.
|
You might also be interested in the following related blog posts
Using T4MVC strongly-typed helpers with Telerik Extensions for ASP.NET MVC
read more
Spec Explorer: A Model-Based Testing tool
read more
12 ASP.NET MVC Best Practices
read more
MvcContrib working on Portable Areas
read more
RELEASED ASP.NET MVC 2 Preview 2
read more
Html Encoding Code Blocks With ASP.NET 4
read more
Presentation Models: Cohesion
read more
Business Apps Example for Silverlight 3 RTM and .NET RIA Services July Update: Part 25: ViewModel
read more
MvcContrib version control has moved to GitHub
read more
How to use Ninject 2 with ASP.NET MVC
read more
|
|
Please login to rate or to leave a comment.