How to code a C# Extension method to turn a Domain Model object into an Interface object?
Asked Answered
E

2

5

When you have a domain object that needs to display as an interface control, like a drop down list, ifwdev suggested creating an extension method to add a .ToSelectList().

The originating object is a List of objects that have properties identical to the .Text and .Value properties of the drop down list. Basically, it's a List of SelectList objects, just not of the same class name.

I imagine you could use reflection to turn the domain object into an interface object. Anyone have any suggestions for C# code that could do this? The SelectList is an MVC drop down list of SelectListItem.

The idea of course is to do something like this in the view:

<%= Html.DropDownList("City", 
         (IEnumerable<SelectListItem>) ViewData["Cities"].ToSelectList() )
Electrify answered 6/4, 2010 at 21:48 Comment(1)
By reflection, I mean read the properties of the source object and match them to the SelectList properties, returning a proper DropDownList selection list.Electrify
K
4

It's easier to make the SelectList part of your ViewModel object.

Anyway, you just have to loop through the IEnumerable and add each item to a new SelectList object and return it.

public static List<SelectListItem> ToSelectList<T>(this IEnumerable<T> enumerable, Func<T, string> text, Func<T, string> value, string defaultOption) 
{ 
    var items = enumerable.Select(f => new SelectListItem() { Text = text(f), Value = value(f) }).ToList(); 
    items.Insert(0, new SelectListItem() { Text = defaultOption, Value = "-1" }); 
    return items; 
} 

How to refactor these 2 similar methods into one?

Kaye answered 6/4, 2010 at 21:51 Comment(4)
+1 for having the formated select list data in the view model. It's much easier and much easier to test.Westleigh
If you please, do you have a link for the ViewModel pattern? Are we talking about making a class for each view in addition to the domain models? I supposed the repository won't return any of these, so do you use factories to create the view models?Electrify
Here you go: nerddinnerbook.s3.amazonaws.com/Part6.htm. The ViewModel is a class object that contains all of the data you need to render the view (including things like SelectLists).Kaye
Heh. I even have that book on my shelf and the notes in my notebook. The part I was missing is: the interface elements are available in the controller. Thanks ;)Electrify
M
4

These are the two extension methods I use to create select lists.

public static IEnumerable<SelectListItem> ToSelectList<T>(this IEnumerable<T> collection, Func<T, string> text, Func<T, string> value)
{
    return collection.ToSelectList(text, value, x => false);
}

public static IEnumerable<SelectListItem> ToSelectList<T>(this IEnumerable<T> collection, Func<T, string> text, Func<T, string> value, Func<T, bool> selected)
{
    return (from item in collection
            select new SelectListItem()
                       {
                           Text = text(item),
                           Value = value(item),
                           Selected = selected(item)
                       });
}

HTHs,
Charles

Mair answered 6/4, 2010 at 22:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.