2009-09-23 32 views
1

我有這樣的「問題」,我有這樣的代碼在我的很多控制器操作:Asp.net - 重構行動

var users = new List<SelectListItem>(); 
foreach(var user in userRepository.GetAll()) 
{ 
var item = new SelectListItem { Text = user.FriendlyName, Value = user.UserId.ToString() }; 

if (User.Identity.Name == user.UserName) 
    item.Selected = true; 

users.Add(item); 
} 

ViewData["Users"] = users; 

你會如何重構這個一個更乾淨的解決方案?我想變幹!

回答

2

我會創造這是適用於List<user>或任何你userRepository.GetAll(擴展方法)返回這樣的話在你的代碼,你可以只用

ViewData["Users"] = userRepository.GetAll().ToSelectList(); 

編輯的代碼示例替換所有這些用法:有2種方法可以做到這一點

public static List<SelectListItem> ToSelectList(this List<Agent> users) 
{ 
    List<SelectListItem> items = new List<int>(); 
    foreach (var user in users) 
    { 
     var item = new SelectListItem { Text = user.FriendlyName, 
           Value = user.UserId.ToString() }; 

     if (User.Identity.Name == user.UserName) 
      item.Selected = true; 

     items.Add(item); 
    } 

    return items; 
} 

和使用情況會是這樣

userRepository.GetAll().ToSelectList(); 

或者,如果你有問題的擴展方法身份是有

public static List<SelectListItem> ToSelectList(this List<Agent> users, 
                 string selectedUserName) 
{ 
    List<SelectListItem> items = new List<int>(); 
    foreach (var user in users) 
    { 
     var item = new SelectListItem { Text = user.FriendlyName, 
           Value = user.UserId.ToString() }; 

     if (user.UserName == selectedUserName) 
      item.Selected = true; 

     items.Add(item); 
    } 

    return items; 
} 

和使用情況會是這樣

userRepository.GetAll().ToSelectList(User.Identity.Name); 
+0

是的,我對其他類似情況有這種方法。問題?是我需要將當前用戶設置爲選定的項目。解決這個問題的最好方法是什麼? – alexn 2009-09-23 13:48:39

+0

User.Identity.Name已經是靜態的,所以你可以在你的擴展方法中使用它。 – 2009-09-23 13:51:30

+0

我可能會爲該代碼添加一些空的檢查,因爲Identity可能並不總是存在,比如在單元測試期間,如果在測試用例中調用它,那麼跳過Selected = true塊會比拋出異常更好。 – 2009-09-23 13:52:55

0

您可以將該邏輯放置在(抽象)BaseController中,然後從中派生所有控制器,讓他們調用BaseController中的方法以根據需要獲取該數據。

如果您需要將它包含在中全部爲您的控制器操作,您也可以將它放置在BaseController中重寫的OnActionExecuting()中。

1

把這些代碼,或代碼的一部分到一個單獨的類 - 我們稱之爲UserService。讓UserService實現IUserService:

public interface IUserService 
{ 
    IEnumerable<SelectListItem> GetUsers(); 
} 

進樣IUserService成通過構造函數注入你的控制器:

public MyController(IUserService userService) 
{ 
    this.userService = userService; 
} 

使用userService場在你的控制器動作,以獲得用戶。

public ViewResult DoSomething() 
{ 
    var users = this.userService.GetUsers(); 
    // the rest of the implementation 
} 
+0

雖然我同意這是很好的設計,但我並不確定它需要爲它創建的整個服務,但它實際上只是一種類型轉換操作。 – 2009-09-23 13:49:27

+0

我也喜歡這個解決方案。我已經有了一個IUserService,所以這很適合。 – alexn 2009-09-23 14:01:26