【问题标题】:How can I use the DRY principle to in ASP.NET MVC to refactor this code?如何在 ASP.NET MVC 中使用 DRY 原则重构此代码?
【发布时间】:2009-03-25 01:41:25
【问题描述】:

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

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

我怎样才能更好地编写这段代码,这样我就不需要每次添加新的选择列表时都需要新的方法?

【问题讨论】:

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


    【解决方案1】:

    这看起来可能是泛型的一个很好的候选:

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

    【讨论】:

    • 你也应该摆脱那个 try/catch 块。它会吃掉所有的异常,不管它们有多严重。如果您遇到一些灾难性错误,那么您确实不想想继续!
    【解决方案2】:

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

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

    这种方法还将列表的构造与正在构造的细节(选择列表)分开。

    【讨论】:

      【解决方案3】:

      我会更进一步,并在控制器代码中编写此代码:

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

      这个在视野中

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多