tags:

views:

205

answers:

2

In an ASP.NET application, I'd like to dynamically render several controls with their properties coming in from an XML document. Here's the kicker: I want to be able to dynamically determine the type of control. So, in my XML document, I have something like this:

    <control>
    <id>myControl1</id>
    <type>CheckBox</type>
    <text>Text For This Control</text>
    </control>

I can get everything to work fine, as far as properties go, so long as I manually instantiate the new control as a checkbox...but I can't seem to figure out how to make it a checkbox, versus a textbox or whatever based on the XML information...

+1  A: 

You could make a Dictionary<string, Type> of valid types or you could create instance by name with Activator.CreateInstance.

Mehrdad Afshari
+4  A: 

You will probably want to be able to control the output beyond the type of Control. My suggestion:

public interface IControlProvider {
    public Control GetControl(XmlElement controlXml);
};

public class ControlProviderFactory : IControlProvider {
    private Dictionary<string,IControlProvider> providers = new Dictionary<string,IControlProvider>();

    public ControlProviderFactory() {
        //Add concrete implementations of IControlProvider for each type
    }

    public Control GetControl(XmlElement controlXml) {
        string type = (controlXml.SelectSingleNode("type") as XmlElement).InnerText;
        if(!providers.ContainsKey(type) throw new Exception("No provider exists for " + type);
        return providers[type].GetControl(controlXml);
    }
}

You could also add a ReflectionControlProvider as a fallback for non registered types and let this use Activator.CreateInstance instead of throwing an Exception when encountering an unknown provider type. This way you get maximum flexibility for both specific control of rendering and dynamic creation.

Johan Öbrink
+1 nice, flexible answer. However, I think it might be overengineering, sometimes.
Mehrdad Afshari
About two months ago, I would have agreed. But since I started using this style of coding in order to satisfy Open Closed principle, I cannot understand why I didn't allways build things that way. It is easy to extend and you run no risk of breaking your code by modifying it since you never modify - just add new providers.
Johan Öbrink
OK I got this far, and getting the type is no longer an issue...but assigning the other properties seems to have become my new problem...? You kinda hinted at the ability to control output beyond the type..any other pointers you could give to set me in right direction? Thanks for your help thus far..
Gus
If you want to control the output of a Checkbox type, create a CheckBoxProvider : IControlProvider and map this. In the CheckboxProvider, you can then use additional attributes from the Xml or just hard code the behaviours and styles you want from the CheckBox.
Johan Öbrink