Hooking your Domain Model and UI Layer

I've recently come across a couple of articles that identify the problem of mapping domain objects to the UI layer.  Paul Wilson suggests that we might be able to solve the problem by implementing a UI Mapper.  A UI Mapper would serve a similar purpose as the OR Mapper.  However, rather then mapping our object to our relational database as we do with our OR Mappers, we use the UI Mapper to map our objects to our user interfaces.  To continue on with some thoughts from the blogosphere we travel over to Jimmy Nilsson blog, where he wonders if the recent buzz surrounding the topic is a sign of things to come.

I haven't put a ton of thought into the topic, however, I think we can gain efficiencies from a UI Mapper as we can with OR Mappers.  On a recent project I didn't exactly flesh out a complete UI Mapper, however, I did do some UI Mapper'ish things to help speed the development of the UI of the application.

On many project in the past I've gotten a little bored writing a bunch of repetitive code to load data within my domain objects into my UI, as well as pulling information out of the UI and placing it into my objects.  The process went something like this...

protected void Page_Load(object sender, EventArgs e) {
  if(!Page.IsPostBack) {
     Customer customer = new CustomerRepository().FindById(99); 
     LoadFormFormCustomer(customer);
  }
}

protected void saveButton_Click(object sender, EventArgs e) {
  if(Page.IsValid) {
    Customer customer = new Customer();
    LoadCustomerFromForm(customer);
  }
}

private Customer LoadCustomerFromForm(Customer customer) {
  customer.FirstName = firstName.Text;
  customer.LastName = lastName.Text;
  // and on and on and on....
}

private void LoadFormFormCustomer(Customer customer) {
  firstName.Text = customer.FirstName;
  lastName.Text = customer.LastName;
  // and on and on and on....
}

Rather then continuing on the same basic path outlined above I set out to automate the process and reduce the amount of code required for creating "edit pages" within my application.  The solution I developed uses reflection to automatically load forms from domain objects, and domains objects from forms.  I created a controller class that takes a domain object and control as parameters.  The controller then loops over the properties of the domain object (via reflection) and finds controls on the form with a matching ID. 

Control foundControl = control.FindControl(property.Name);

If a control is found for the property the controller loads the control with the value within the associated properties of the domain object.  With this infrastructure in place the edit page for the Customer becomes much simpler:

public class CustomerEdit : Steve.Eichert.Sample.Web.UI.EditPage {
  
protected override Type DomainType() {
   
return typeof(Customer);
  
}
}

Could UI Mappers be the next big thing?  Maybe, maybe not, all I know is my simple UI Mapper saved me from writing a bunch of boring repetative code and allowed me to concentrate on developing the domain logic within the application which in my opinion is a very good thing.

# re: Hooking your Domain Model and UI Layer

Monday, July 26, 2004 5:45 PM by John Rusk    
Steve,

What about using DataBinding? I haven't used it much for WebForms, but we're using it on my current WinForms project and its working well.

The UI contains very little logic, in fact it doesn't contain much code at all. It's just databound to the business entities.

John

# re: Hooking your Domain Model and UI Layer

Monday, July 26, 2004 7:32 PM by Thomas Eyde    
You still have to write the databinding code, then there are the formatting problems when things are not strings. Besides, databinding does not work on public fields. This will force you to implement properties when fields would do, and clutter the code.

I can't see databinding would solve the problem alone, but you could be right in that a UI mapper should/could build on databinding.

I wouldn't use it, though, because I use public fields whenever I don't need to encapsulate them, which seems to be almost never.

# re: Hooking your Domain Model and UI Layer

Monday, July 26, 2004 9:07 PM by Thomas Tomiczek    
::You still have to write the databinding code

Nope, sorry. YOu drop an ObjectView on a form, you are set.

::then there are the formatting problems when
::things are not strings.

Really? Sorry to ask, I have no issues at all using powerfull third party visual controls (Infragistics) in a pretty complex scenario.

::, databinding does not work on public
::fields. This will force you to implement
::properties when fields would do, and clutter
::the code.

Not a problem at all. First, you CAN bind to public fields. It , again, requires about a page of code once. Yeah, thingsw are alittle more powerfull than you think.

Second, per definition, youdo not have public fields. It's hthis thing about OO programming and encapsulation.

::I wouldn't use it, though, because I use
::public fields whenever I don't need to
::encapsulate them, which seems to be almost
::never.

WHOW. 100% of my property write accessors has logic in them (guess what). What exactly are you ignoring? Maybe change events (your objects are so "dump" they can not tell other objects a value changed - you are in trouble then)? Object level validation (the OBJECT is responsible that the value makes sense, not the UI). What else?

Sorry, your comment just did not sound like well thought out.



# re: Hooking your Domain Model and UI Layer

Monday, July 26, 2004 11:09 PM by Mark Bonafe    
I think you are on to something, Steve. I'd pretty much ignore Thomas' remarks. Depending on your application architecture, "drag and drop" binding may not be a good solution.

Your answer to the problem is much cleaner. This is the first I've heard of UI mappers. Sounds like OR mapping arguments all over again because there are hundreds of different solutions to the problem.

# re: Hooking your Domain Model and UI Layer

Monday, July 26, 2004 11:45 PM by Darrell    
Brendan ( <a target="_new" href="http://dotnetjunkies.com/WebLog/BsBlog/">http://dotnetjunkies.com/WebLog/BsBlog/</a> ) has been doing this for quite a while and has had significant success.

# re: Hooking your Domain Model and UI Layer

Tuesday, July 27, 2004 3:04 AM by Steve    
DataBinding could be an option to consider. My solution was a little simpler (IMO) and didn't involve all that much code to implement.

The reasons for an UI Mapper closely mirror the reasons for OR Mappers. The important thing is to remember that UI Mappers and OR Mappers aren't silver bullets, although some people will preach that they be used for everyhing, my theory is that they should be used for the things that they'll work well with and not forced upon everything.

# re: Hooking your Domain Model and UI Layer

Tuesday, July 27, 2004 3:05 AM by Steve    
I'll have to check out Brenden's blog, has he posted much on the topic? Hrm, maybe I should get off my ass and go look myself ;)

# re: Hooking your Domain Model and UI Layer

Wednesday, July 28, 2004 5:28 AM by Thomas Eyde    
I was thinking more on all the work I have to do if I were writing this from scratch. I haven't tried the tools from Infragistics, but it looks like I should have a closer look.

But this statement provokes me:
&quot;Second, per definition, youdo not have public fields. It's hthis thing about OO programming and encapsulation.&quot;

Which definition, excactly, are you talking about? Encapsulation is fine, but there is another important one: Do the simplest thing that could possibly work.

Public field is the simplest thing when you don't need logic. I don't like to encapsulate just for the sake of it. There is no functional or behavioural difference between a property and a public field when there are no logic, except from databinding.

I am not ignoring everything. What should I validate on readonly objects? Which changes should I notify? Validation on property level? I don't do that. Do your users really like to be interupted with a validation message on every field change? Or do they like to fix one mistake at a time? Mine don't. They usually want to complete the task as quickly as possible. That means listing all mistakes at once.

You will find my validation code in two places: One is validators in the gui to secure a valid type is entered (no text in numeric fields), the second is in the Save() method. Here all mistakes are collected and reported back in one go. If the validation starts to get complex, I move them to a separate object.

And I think logic belongs in methods, not in properties.

And then all my code is usually used by another code written by the same project, so I am not that paranoid about misuse like someone writing to a field which is not supposed to change. I have yet to see that happen.

But I am all in favour of UI mappers, just in case that got lost in the rant.

# re: Hooking your Domain Model and UI Layer

Wednesday, July 28, 2004 5:44 AM by Steve    
Thomas, Rant on brotha!!!

# re: Hooking your Domain Model and UI Layer

Wednesday, July 28, 2004 11:17 AM by David Hayden    
Steve,

I have to say I really enjoy your posts!

My code-behind for ASPX pages is similar to your original monotonous code, but I utilize some custom Codesmith templates to save me the time and effort.

For your basic 3-tier web database applications, I essentially just create the database and let Codesmith spit out the data layer, business layer and UI layer. My homemade templates literally take a minute to run.

The templates aren't perfect and require me to stick to some database standards and take about a day of monotonous tweeking at worst case, but to be able to put together a custom web database application in only two days is not bad in my opinion. At least not for my humble small business :)

Obviously you wouldn't be so lucky for complex applications, but if you find yourself typing repetitive code, you can bet you can save yourself a whole lot of time by visiting your friendly neighborhood code generator.

Although a &quot;UI Mapper&quot; has its place, you can certainly accomplish a lot of redundant UI code with code generators. This will allow you to be in charge of the implementation as well as gain peformance over reflection and other exploratory techniques used by a &quot;UI Mapper&quot;.

# re: Hooking your Domain Model and UI Layer

Wednesday, July 28, 2004 12:15 PM by Steve    
David,

Thanks!

I've gone the code generation route as well. There are obviously some advantages and disadvantages to each method. Don't tell anyone but I still haven't taken the time to use CodeSmith :(. I know, I know!

Although I agree that code generators can put you a little more in charge, I'm afraid I can't take the performance argument. I usually (not always) use reflection to create dynamic assemblies which perform just as good as when you generate or write the code by hand.

Back in the day I created my dynamic assemblies using using Reflection.Emit, however, there's only so much emitting one guy can take. Now I usually generate the code for a class using reflection, and then compile it into a dynamic assembly using CodeDom.

Anyway, not bad at all for your &quot;humble small business.&quot; Any pointers for a wanna be &quot;humble small business&quot; owner?

Cheers,
Steve

# re: Hooking your Domain Model and UI Layer

Thursday, July 29, 2004 8:55 AM by David Hayden    
Point well-taken. I assumed there would be some sort of a performance cost by using reflection, but I have not tried it myself. Your experience speaks volumes.

As for pointers, I'm not sure I'm qualified to give advice :) However, I have been toying with the idea of talking more about consulting and business in my blog. If I ever take the plunge, I will shoot you an email.

Great post.

# re: Hooking your Domain Model and UI Layer

Friday, July 30, 2004 1:51 AM by Oskar Austegard    
A very timely entry on ASP.NET's Daily Articles
<a target="_new" href="http://www.codeproject.com/aspnet/manubindingmanager.asp">http://www.codeproject.com/aspnet/manubindingmanager.asp</a>

And Steve, you really need to start using CodeSmith...

# re: Hooking your Domain Model and UI Layer

Friday, July 30, 2004 4:22 AM by Steve    
I know!

Post a Comment

 
 
Prove you're not a spammer: 
0 + 1 =