Rob just put the M into MVC using Subsonic and a Subsonic MVC Template. The template allows you to go from 0 to functioning application in less time than it takes to listen to a Rob Zombie song. Fantastic work by Rob C, and it leads nicely into the actual question behind this series of posts:
“I have created domain entities like Customer, Order, etc. They come out of repository classes backed by NHibernate. I’m wondering if I send them directly to the view or if I create a ViewModel class to hold data. I’m confused by all the terminology”.
This is a difficult question to answer without looking at the specifics of an application, but what follows is my opinion on the matter.
To me, an entity is a business object that is full of data and behavior. The data probably comes from a database. The behavior comes from code you write to implement “business logic”. Perhaps the business logic is simple validation code, or perhaps the business logic is code that talks to other entities and objects in your business layer to coordinate more complex business goals – like placing an order and running a long business process.
An entity exists to serve the business layer. If the customer asks you to change how the order total displays, you’ll make the change in the UI and not touch any entities. But, if the customer asks you to change how the order total is calculated, you’ll make the change in the business logic and possibly modify the Order entity itself. Since the entity exists to serve the business layer you should assume the business layer owns all entities.
It is reasonable to share these business layer owned entities with the UI layer in many applications. This is what happens if you use Rob’s templates. Here is an excerpt from a template generated controller:
// GET: /Movie/Edit/5 public ActionResult Edit(int id) { var item = _repository.GetByKey(id); return View(item); } // // POST: /Movie/Edit/5 [AcceptVerbs(HttpVerbs.Post)] public ActionResult Edit(Movie item) { if (ModelState.IsValid) { string resultMessage = ""; try { _repository.Update(item); resultMessage = item.DescriptorValue() + " updated!"; } // ... } }
Entities come out of repositories and go directly into a view. During a save operation, the entities materialize from the view and go to a repository. The approach is simple to understand, and works well if you can picture your software like the following:
The entities are round pegs, while the business logic and views are round holes. There is no friction because the entities fit the needs of both layers perfectly. What you are building in these scenarios is a “forms-over-data” application. These types of applications usually have the following characteristics:
I’m not trying to make “forms-over-data” applications sound trivial or stupid. If all you need is a data entry application then you don't want to add unnecessary complexity to your software. Share entities with the UI views and keep things simple. Simple works well.
In the next post we’ll talk about when to avoid sharing entities with your UI layer. As you might guess, it will involve a diagram like this: