views:

22

answers:

3

Say you have an abstract base class Task which is a task a user can complete. There are two concrete Tasks: SimpleTask and ChecklistTask. What if you wanted the (ASP.NET) UI to show a different control based on which type of Task it is?

In WPF you could use DataTemplates, but what is a nice way to do it in ASP.NET? We are trying to avoid a switch statement by the way. We have other pieces of code with long switch statement which started out small, but grew in time. That's what we're trying to avoid.

Is there a design pattern for things like this? We can't let the Task classes 'know' the UI classes because they're are domain classes. Or is a switch statement the best we can do (if necessary hidden in a seperate 'factory' class)?

A: 

Assume your SimpleTask implemented in SimpleTask.ascx, and ChecklistTask in ChecklistTask.ascx. Then put into metainfo (in any way you need it to create particular control) path where .ascx resides (eg.: "~/MyControls/SimpleTask.ascx" ).

And at last: embed control with TemplateControl.LoadControl

Dewfy
That ties your domain a little to the UI, but more problematic is that the application would no longer work when you move your controls somewhere else. It's a fairly large application we're working on, so that wouldn't be a safe, future-proof option, I believe.
Peter
A: 

I love the "Isolation" part of any design pattern, look I think you should make tow UI implementations for both simple and checklist tasks, and both are just a black box for itself, then on another control or page you can use ItemTemplate if you going to list some tasks and in this ItemTemplate you just put a condition to check the type of the task and on it call a method on this page that render the html of the right type (Simple or Checklist)

Mustafa Magdy
That's what we're trying to avoid: the conditional checks. Because what happens if you have 20 types of tasks? But it seems it will be unavoidable. Then best to put it in a seperate class.
Peter
+1  A: 

Something, somewhere, has to know how to map the Task subclass to the UI control. Period. The only question is where to put this knowledge.

  1. The Task itself
  2. A class that can use data retrieved from the Task to find an appropriate control
  3. The code that actually gives the Task out (why can't it give the UI control instead?)
  4. Some code that maps the Task class to the UI control, possibly via attributes and reflection.
  5. Some other kind of metadata.
kyoryu
The Task can't 'know' the UI control, because it's a domain class. Apart from then coupling the domain to the UI, it's even impossible. The UI has a reference to the domain assembly and if you'd want the domain class to give the UI control, then you'd have circular dependencies.
Peter
That was one possibility. The overall point is that *something* has to know what the mapping is - the only question is really, where does that code belong, and how does it work? In fact, I'd probably start by writing a class that can do the mapping, even without the data... figure out how to generate the mapping as a separate step and a separate class.
kyoryu
Yes, thanks for the other possibilities. Indeed, something will have to do the mapping. I was just wondering if there was a clean way to do it, instead of through a big if-else or switch statement. Thanks anyway!
Peter
Depending on the overall app, I'd consider adding a custom attribute to the UI control which specified the type of Task it mapped to. Use reflection to gather those, populate a Dictionary, and then do a lookup when you get the actual Task. Still avoids the switch statement.
kyoryu