Using an anonymous object as the model for your Spark view
Well another post about Spark, I’ve been spending a couple of hours with the library and I really like it. On one of my previous posts Byron Sommardahl asked if it was possible to use an anonymous object as the model of your Spark view. I proposed a solution but I didn’t really have an idea if it actually worked. Because I was curious if it would work I fired up Visual Studio.
A little warning before we dive in, my gut feeling says that the code could be prettier but it does work. Some reflection is used to get the job done.
As a base of my solution I started out with the code I’ve written in my previous post on how to generate html with Spark. I recommending rereading it before continuing. This is my new, more generic Spark view which will be used to generate HTML:
using System;
using Spark;
namespace SparkAnonymousView.Code
{
public abstract class AnonymousSparkView : AbstractSparkView
{
public object Data { get; set; }
public Type AnonymousType { get; set; }
}
}
Where in the previous post we had a data transfer object with a specific type which had all the necessary data, now the Data property is of the object type. There is a second property which will hold a reference to our Anonymous type.
The Data object with which we will be working is this:
var data = new
{
TestProperty1 = "Test Property 1 Value",
TestProperty2 = "Test Property 2 Value",
TestProperty3 = "Test Property 3 Value",
TestProperty4 = "Test Property 4 Value"
};
A simple Anonymous object with 4 properties will be our DataTransferObject (DTO). We will initialize our AnonymousSparkView with the following data:
view.Data = data;
view.AnonymousType = data.GetType();
Our DTO is filled out into the Data object. The type of the anonymous DTO is filled out in the AnonymousType property. Now is the time to fill out the necessary data in our template. This is the template:
<h1>Generated HTML</h1> <ul>
<li>${AnonymousType.GetProperty("TestProperty1").GetValue(Data, null)}</li>
<li>${AnonymousType.GetProperty("TestProperty2").GetValue(Data, null)}</li>
<li>${AnonymousType.GetProperty("TestProperty3").GetValue(Data, null)}</li>
<li>${AnonymousType.GetProperty("TestProperty4").GetValue(Data, null)}</li>
</ul>
This little snippet uses a bit of Reflection magic to read the properties from our anonymous object. Between the ${ } token in Spark you can put a property from your view or you can put in a c# expression. We get the AnonymousType property of our view and get a specific property of our DTO, which is an anonymous object, via the GetProperty function. Then we can get the value of a specific property by calling GetValue on the found property.
It’s not pretty but it does work. I tried out a couple of methods that didn’t use Reflection but none of them worked. I am planning of putting all future code on my GitHub account. You can find the repository here and fork it if you want. Any comments or alternative solutions are welcome, as always.