Late Binding of C# objects from NHibernate into the ASP.NET DataGrid control
Wednesday 26th April 2006 at 1:57 pmIt’s not a full example with code downloads, but here’s an example of late binding in C#, when we don’t know whether a class being bound into a DataGrid is going to be of type Article, Vacancy, Image, or whatever. I’ve found this to be a good approach when customizing a DataGrid that we can re-use in our internally-developed content management system.
Since the objects we get back from NHibernate, wonderfully enough, are just objects of the type we ask for instead of some stupid intermediate typeless object contained in a DataSet, we can just bind them into the DataGrid. The one thing that’s necessary is that we need to know anything going into the DataGrid needs to implement certain properties, like Title and Active.
First, we define an interface that content objects must implement:
[code]using System;
using System.Collections;
namespace com.headlondon.cms.models
{
///
/// implement. Other classes, such as headcms.admin.common.controls.datagrid.HeadGrid
/// rely on these details to be able to do late binding.
///
interface IContent
{
int Id { get; set; }
string Title { get; set; }
bool Active { get; set; }
void Save();
void Delete();
}
}
[/code]
Then we make sure our concrete classes do in fact implement this interface:
[code]using System;
using System.Collections;
using com.headlondon.cms.dataaccess;
namespace com.headlondon.cms.models
{
///
/// also used by other classes such as Vacancy and FAQ for inheritance.
///
public class Article : IContent
{
private ArticleDao dao = new ArticleDao();
private int id;
private string title;
private string body;
private bool active;
///
///
public Article()
{
Id = -1;
Active = false;
}
///
///
public void Save()
{
dao.Save(this);
}
public static IList List()
{
ArticleDao dao = new ArticleDao();
return dao.List(typeof(Article));
}
///
///
public static IList List(string property, object propertyValue)
{
ArticleDao dao = new ArticleDao();
return dao.ListByPropertyValue(typeof(Article), property, propertyValue);
}
///
///
public static IList List(string property, object propertyValue, string orderPropertyName, string orderValue)
{
ArticleDao dao = new ArticleDao();
return dao.ListByPropertyValueOrderBy(typeof(Article), property, propertyValue, orderPropertyName, orderValue);
}
///
///
public static IList List(string orderPropertyName, string orderValue)
{
ArticleDao dao = new ArticleDao();
return dao.List(typeof(Article), orderPropertyName, orderValue);
}
///
///
public static Article Get(int id)
{
ArticleDao dao = new ArticleDao();
return dao.Get(typeof(Article), id) as Article;
}
///
///
public void Delete()
{
dao.Delete(this);
}
// Accessors
///
///
public int Id
{
get { return id; }
set { id = value; }
}
///
///
public string Title
{
get { return title; }
set { title = value; }
}
///
///
public string Body
{
get { return body; }
set { body = value; }
}
///
///
public bool Active
{
get { return active; }
set { active = value; }
}
}
}[/code]
Then when we want to grab a piece of content from the database and stick it in a DataGrid using a DataBind method call, we don’t have to worry about what its concrete class is, we just say something like this:
[code]
///
/// to the CheckBox.
///
/// Any type in the DataGrid must implement the interface IContent, which specifies that the
/// item must have an Id, Active, and a bunch of other properties.
///
private void BindData(object sender, EventArgs e)
{
CheckBox checkBox = (CheckBox)sender;
DataGridItem container = (DataGridItem) checkBox.NamingContainer;
IContent content = (IContent)container.DataItem;
checkBox.Checked = content.Active;
HtmlInputHidden oHid = (HtmlInputHidden)container.FindControl("oHid");
oHid.Value = content.Id.ToString();
}
[/code]
That code was from a custom CheckBoxItem class, the custom DataGrid class does something like this during its DataBind event:
[code]
IContent content = (IContent) e.Item.DataItem;
((HyperLink)e.Item.Cells[0].FindControl("lblC1")).Text = content.Title;
((HyperLink)e.Item.Cells[0].FindControl("lblC1")).NavigateUrl = formPath + content.Id;
[/code]
This blog post is just to put you on the right track, if you need more help with this sort of thing just reply in the comments. It’s been a pleasant way to get a lot of functionality out of very little code.
Web References:
If you’re not familiar with the basic concepts, there is a good discussion of late binding in C# and VB.NET here. Oddly it doesn’t include this interface trick above, so maybe this will help someone.

Just as a note: thinking about it some more, I really prefer this way of doing late binding to the loose-typing VB.NET way. The reason is pretty simple – there is absolutely no way to screw it up, due to type safety. In VB.NET, you could just say something like:
Option Strict Off
…and then proceed to access any property or method of the Article object (which is in fact just an object). The trouble would be that if you blew it and forgot to implement, let’s say, Title in one of your classes, you’d get a runtime error when a user tried to access your code. Using the IContent interface ensures that any class that implements IContent *must* have a Title, Id, etc. So, even in VB.NET, this technique of casting to an interface is still the way to go.