It is common to have a view model that contains a list of select list items ( IEnumerable ). However, I get a little annoyed when I see a select list item getting initialized like this:
Widgets = db.Widgets.FindAll().Select(x => new SelectListItem() { Text = x.Name, Value = x.Value });
Although this is legal syntax its just a little bit too ugly for my liking. In an effort to make life simpler I came up with the following helper class:
public static class SelectListFactory
{
public static IEnumerable<SelectListItem> BuildList<T>(IEnumerable<T> items, Func<T, SelectListItem> func)
{
return items.Select(func);
}
public static IEnumerable<SelectListItem> BuildList<T>(
IEnumerable<T> items,
Func<T, string> text,
Func<T, string> value = null,
Func<T, Boolean> selected = null)
{
return items.Select(x => new SelectListItem{
Text = text.Invoke(x),
Value = value == null ? text.Invoke(x) : value.Invoke(x),
Selected = selected == null ? false : selected.Invoke(x)
});
}
}
With the help of our new SelectListFactory we can now re-write that first block of code as:
Widgets = SelectListFactory.BuildList( db.Widgets.FindAll(), x => x.Name, x => x.Value );
Hmm, not to shabby. However, I think an extension method could make it even cleaner...
public static class SelectListExtensions
{
public static IEnumerable<SelectListItem> BuildList<T>(
this IEnumerable<T> items,
Func<T, string> text,
Func<T, string> value = null,
Func<T, Boolean> selected = null
)
{
return SelectListFactory.BuildList(items, text, value, selected);
}
}
So now lets rewrite the method using our new extension method...
Widgets = db.Widgets.BuildList( x => x.Name, x => x.Value );
Now that is considerably better than what we started with! Happy Coding!