views:

68

answers:

2

I am just at the brink of going "Ah HA!" when it comes to coding Domain Driven Design. The question is How and where to define a MVC ActionMethod parameter class that involves an entity, a value object, and a few extra fields? The entity and value object classes are defined in my repository.

Do I:

  1. Create a custom class in the repository implementing the other classes (to get the properties of all in a single class), and add a few more properties for the extra fields?
  2. Create the entity / value object poco classes in a repository and create a composite class referencing these objects in my controller class, then use this as the ActionMethod parameter type?
  3. Something else?

The request form simply collects a few Customer class fields, a mailing address, and a few form specifics like how they found us. The content is not important, only that it holds information from multiple pocos.

I know MVC will match the fields of the posted form to the properties of the Poco in the ActionMethod parameter like the following:

[AcceptVerbs(HttpVerbs.Get)]
public ActionResult RequestCatalog()

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult RequestCatalog(Customer customer)

So customer.firstName is bound to firstName in the posted form automatically.

I have the following:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult RequestCatalog(string fname, string lname, string address,
    string city, string state, string zip, string phone, string howTheyFoundUs)

But want to have something like:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult RequestCatalog( RequestForm requestForm)

Any thoughts?

+1  A: 

There is nothing to stop you using Request.Form in your action method.

E.g.

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult RequestCatalog(Customer customer)
{
    var howTheyFoundUs = Request.Form["howTheyFoundUs"];

    // ...
}
AdamRalph
Can you do (Customer customer, string howTheyFoundUs) where Customer is an object with nested objects and have the form fields match the object properties even if they are nested?
Dr. Zim
+2  A: 

First of all you must realize that the Domain Model must be defined independently of the run-time framework (MVC). Imagine that in the future you must be able to expose the Domain Model as a WCF service, or a WPF/Silverlight rich client, or a batch job, or something else...

This means that all modeling must be unconstrained by technical details. How you store your data and the specifics of how the Domain Objects are consumed must be (largely) ignored at this stage of the design process.

You must always ask yourself: Does this class make sense as a part of the pure domain?

In you specific case, most of your input sounds like it belongs on a Customer class with a structure similar to this

public class Customer
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Phone { get; set; }
    public Address Address { get; set; }
}

and the Address class is defined similarly.

Now the question you need to ask yourself (or any Domain Experts you are working with): Does the howTheyFoundUs belong on the Customer class? Or is is a Domain concept in its own right? Or is it really just an application-specific piece of data that doesn't have anything to do with the Domain Model at all? The answer to such questions will guide how you end up modeling your input.

As an aside, the Phone property above looks dubious to me, but is a pretty good example on how implementation details (in this case ASP.NET MVC) may leak into the model.

A phone number should really be a Value Object in its own right (see this blog post for a related treatment of this subject), but the default ModelBinder of ASP.NET requres a primite type. A better option would be to implement a custom ModelBinder that can parse a phone number into a proper object.

Mark Seemann
Thank you for your detailed answer. It helps me a lot. In reading your post, I am relieved that MVC classes should not affect Repository classes. I am impressed you can take read only value objects and simply load them within the entity objects. I think in MVC2 that (Customer customer) in the ActionMethod should bind any matching form fields to the Customer object properties, although I don't know if it handles nested objects.So the big question is can MVC 2 match nested object properties in the ActionMethod parameters, and should I define these composite classes in the controller class?
Dr. Zim
IIRC ASP.NET MVC 1 can already do limited modelbinding of nested classes. I can't answer your MVC 2 questions because I haven't started using it yet.
Mark Seemann