views:

215

answers:

3

I have several methods in one of my controllers that does this:

ViewData["Customers"] = LoadCustomers();
ViewData["Employees"] = LoadEmployees();
ViewData["Statuses"] = LoadStatuses();
etc......

Here is LoadCustomers(), but LoadEmployees, LoadStatuses and all the others are virtually the exact same logic:

private static SelectList LoadCustomers()
    {
        IList<Customer> customers;
        try
        {
            IServiceCallService scService = new ServiceCallService();
            customers = scService.GetCustomers();
            Customer c = new Customer
            {
                ID = "",
                Name = "-- Select a Facility --"
            };
            customers.Insert(0, c);
        }
        catch
        {
            customers = new List<Customer>();
            Customer c = new Customer
            {
                ID = "",
                Name = "-- No Facilities on File --"
            };
            customers.Insert(0, c);
        }

        return new SelectList(customers, "ID", "Name");
    }

How can I write this code better so I don't need a new method everytime I add a new select list?

+4  A: 

This looks like it might be a good candidate for generics:

private static SelectList LoadItems<T>() where T : new, ... 
{                                                // Add any additional interfaces
                                                 // that need to be supported by T
                                                 // for your Load method to work,
                                                 // as appropriate.
    IList<T> items;
    try
    {
        IServiceCallService scService = new ServiceCallService();
        results = scService.Get<T>();  // You'll need to replace GetCustomers() with
                                       //   a generic Get<T> method.

        // ...
    }
    catch         // Really needed? What are you trying to catch here? (This catches
    {             //   everything silently. I suspect this is overkill.)
        // ...
    }

    return new SelectList(items, "ID", "Name");
}
John Feminella
You should also get rid of that try/catch block. It will eat all exceptions, no matter how serious they are. If you get some catastrophic error, then you do *not* want to continue!
John Saunders
A: 

You could also try a more functional approach.

public IList<T> Load<T>(Func<IList<T>> getList, T prependItem)
{
    var list = getList();
    list.Insert(0, prependItem);
    return list;
}

Usage:

var prependItem = new Customer { ID = "", Name = "-- Select a Facility --" };
ViewData["Customers"] = new SelectList(
    Load(new ServiceCallService().GetCustomers(), prependItem),
    "ID", "Name");

This approach also separates the construction of the list from the details of what is being constructed - a SelectList.

Jonathan Parker
A: 

I'd go even further and write this in controller code:

 ViewData["Customers"] = new SelectList(
      new ServiceCallService().GetCustomers(),
      "ID","Name")

and this in view

<%= Html.DropDownList("Customers",
     ((SelectList)ViewData["Customers"]).Count() > 0 ? 
    "-- Select a Facility --" : "-- No Facilities on File --" ) %>
Alexander Taran