Where does this go? Applying SoC to dynamic data – Part 1

Since a major goal of Dynamic Data is to separate the business logic from the user interface, let’s look at a few areas where these concepts still blend and their alternatives.

Today we look at the…

UIHintAttribute

Attributes like System.ComponentModel.DataAnnotations.UIHintAttribute are placed on the properties of your Entity class. That’s the business layer. Yet UIHintAttribute explicitly determines which Field Template is used. The Field Template is in the UI layer.

The business layer should influence the user interface into picking a Field Template, but it shouldn’t know anything about specific Field Templates. It’s influence comes from identifying the data type of the property (table column), such as a date or integer. The business layer has two ways to identify the type:

  • The DataTypeAttribute
  • The property’s type (when there is no DataTypeAttribute assigned)
public class Products
{
public string ProductName { get; set; }

[DataType(DataType.Currency)]
public decimal UnitPrice { get; set; }

[DataType(DataType.Date)]
public DateTime RestockDate { get; set; }
}

Your app will have many Field Template files whose file name matches a data type, like “Text.ascx” (for string types), “Currency.ascx” and “Date.ascx”. These are the default user interfaces for a data type. If you need something different from the default, create a new Field Template file and give it a unique name. Perhaps you want a Date label to be formatted using the long date pattern. You might name your new Field Template “DateLongPattern.ascx”.

How do you fix this?

Here’s how to replace the UIHintAttribute.

  1. Use the DataTypeAttribute to specify a general type. What about the case when the enumerated type System.ComponentModel.DataAnnotations.DataType does not have an element to match your needs? Initially you would think to use the UIHintAttribute. Instead, pass a string name of the type to the DataTypeAttribute.
    [DataType("Measurement")]
    public decimal Distance { get; set; }

  2. The user interface developer specifies the Field Template’s name in the UIHint property found on the DynamicControl and DynamicField objects.
    <asp:DynamicControl id="RestockDate" runat="server" UIHint="DateLongPattern" />

 



2 Comments

  • I don't really see the difference here. You're still choosing a Field Template, you're just using the DataType to do it instead of the UIHint.

    You still have to be aware of what Field Templates exist because you're typing their names into the DataType attribute.

    Or am I missing something?
    [Peter's comments] Hi David. The initial collection of Field Template files reflects the available data types of any application. As the application is built, the web form developer will need to create specialized cases of those Field Templates. For example, make the TextBox of Text_Edit.ascx use the style sheet "xyz".
    The business logic should express the data type of a property through the DataTypeAttribute. It maps to that initial collection of Field Templates, yet it really doesn't care about the actual content. The UIHintAttribute expressly picks a single Field Template, demanding a specific UI.
    The DataTypeAttribute participates in other ways too. Validators are created (like setting the Type property on the CompareValidator when its Operator property is set to DataTypeCheck).
    Also note that the DataTypeAttribute can identify a type that is not defined as a Field Template, like DataType("Measurement"). Dynamic Data can still handle it by using a fallback procedure in its Field Template Factory. It will fall back to the real type of the property (like string or decimal) to locate a Field Template.


  • Ok, so I was missing something.

    It seems like it's way too easy to do the wrong thing here - a UI property simply shouldn't be available as an attribute; as you've demonstrated it leads to shortcuts being taken that violate separation of concerns.

Comments have been disabled for this content.