Introduction
Most of the online stores support a feature where the user can select multiple products from different vendors and compare them. For example, in http://www.sonystyle.com/, user can select different models available in digital cameras and do a comparison between them. This comparison table basically lists the key features that the user will be looking for in a digital camera and displays each model's capability. An example of such a comparison table is shown below:
Recently I was reading the requirements given by one of our business folks and I realized that it was similar to the comparison table displayed in these websites. Since the development platform is .NET, I decided to exploit the features of .NET.
Problem Definition
- User must be able to select different objects and do a comparison of their properties. Objects compared will be always of the same type.
- Must be able to reuse this implementation in other existing and new web applications.
Objectives
- Generic scheme so that this can be reused in multiple projects.
- Scheme should be simple, easy to understand, extensible and customizable.
Features used
After thinking for a while, I decided to use the following features of .NET to meet the objectives.
- Attributes
- Reflection
- Web Custom Control (ASP.NET)
How the scheme works
I defined an attribute called CompareAttribute
which has two properties namely DisplayTitle
and DisplayOrder
. Any class whose properties have to be listed in the comparison table should be decorated with this attribute.
[AttributeUsage(AttributeTargets.Property)]
public class CompareAttribute : System.Attribute
{
private int __displayOrder = 0;
private string __displayName = string.Empty;
public CompareAttribute(int DisplayOrder, string DisplayName)
{
__displayOrder = DisplayOrder;
__displayName = (DisplayName == null) ? "<undefined>" :
DisplayName.Trim();
}
public int DisplayOrder
{
get
{
return __displayOrder;
}
}
public string DisplayName
{
get
{
return __displayName;
}
}
}
I defined a web custom control called DiffTable
which contains the logic to render the comparison table. This custom control exposes a property called ObjectsToCompare
of type ArrayList
. If you provide an arraylist with the list of objects that you want to compare, then the control will do the necessary magic and displays the Comparison
table.
To illustrate this scheme, I have defined a sample class called Camera
. This camera class has five properties - Name
, Model
, Price
, Warranty
and HasCarlZeiss
. I have decorated each property with the compare attribute.
Class properties decorated with the compare attribute will look like:
[Compare(5, "Warranty Info")]
public string Warranty
{
get
{
return __warranty;
}
set
{
__warranty = (value == null) ? string.Empty : value.Trim();
}
}
The custom control uses reflection to identify the type of objects being compared. Also it make sure that the user has assigned at least 2 object instances for comparison.
private SortedList FetchComparableProperties(Type type)
{
SortedList prps = new SortedList(32);
CompareAttribute cmp = null;
foreach(PropertyInfo prpInfo in type.GetProperties())
{
cmp = (CompareAttribute)Attribute.GetCustomAttribute(
prpInfo, typeof(CompareAttribute));
if(cmp != null)
{
if(prps.ContainsKey(cmp.DisplayOrder))
throw new Exception(string.Format(
"A property with the same display" +
" order of {0} already exists.",
cmp.DisplayOrder));
prps.Add(cmp.DisplayOrder, prpInfo);
}
}
return prps;
}
The above code inside the custom control shows the logic used to identify the properties marked with CompareAttribute
and arrange the properties in the sorted order based on the Display
Order value specified in the compare attribute decoration.
The download contains a sample web application which displays the comparison table generated by this scheme. The download also contains the source code of the web custom control. I have added enough documentation to each functions within the web custom control for easy understanding.
Highlights
- Since this scheme is based on metadata, even if new classes are added to the solution in the future, just by decorating the properties with the compare attribute will enable instances of this class to be compared without any change to the existing code.
- Since the core logic is implemented as a web custom control, it is self contained and easily distributable. This control can be reused in multiple web applications.
Improvement
- This scheme can be extended to support comparison with grouping - related properties will be grouped under a heading (similar to the feature in http://www.dealtime.com/).
- Image can be shown in the comparison table for each objects being compared by adding properties like ImageUrl.
- And more...
Conclusion
To implement functionality similar to this in classic ASP, it will be very tedious and more time consuming. With the help of .NET framework, things have become very easy and achievable in short time. I assume that everyone will appreciate the fact that .NET is making our life much easier.