如何在ASP.NET MVC中使用DRY原则来重构此代码?

时间:2009-03-25 01:41:25

标签: c# asp.net-mvc coding-style dry

我的一个控制器中有几种方法可以做到这一点:

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

这是LoadCustomers(),但LoadEmployees,LoadStatuses和所有其他几乎完全相同的逻辑:

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");
    }

如何更好地编写此代码,以便每次添加新的选择列表时都不需要新方法?

3 个答案:

答案 0 :(得分:5)

看起来它可能是仿制药的一个很好的候选者:

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");
}

答案 1 :(得分:0)

你也可以尝试更实用的方法。

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

用法:

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

这种方法还将列表的构造与正在构造的内容的细节分开 - 一个SelectList。

答案 2 :(得分:0)

我会更进一步,在控制器代码中写这个:

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

并且在视图中

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