2009-09-23 6 views
1

J'ai ce « problème » que j'ai le code comme ceci dans plusieurs de mes actions de contrôleur:Asp.net - Action Refactor

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; 

Comment décririez-vous ce factoriser à une solution plus propre? Je veux devenir SEC!

Répondre

2

Je créerais que ce soit une méthode d'extension appliquée à List<user> ou quel que soit votre userRepository.GetAll() retourne donc alors dans votre code, vous pouvez remplacer tous ces usages avec juste

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

Modifier exemple de code : Il y a 2 façons, vous pouvez le faire

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

et l'utilisation serait comme

userRepository.GetAll().ToSelectList(); 

Ou si vous avez des problèmes avec l'identité étant dans la méthode d'extension ont

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

et l'utilisation serait comme

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

Oui, j'ai cette approche sur d'autres situations similaires. Le problème? est que je dois définir l'utilisateur actuel comme l'élément sélectionné. Quelle serait la meilleure façon de résoudre cela? – alexn

+0

User.Identity.Name est déjà statique, vous pouvez donc l'utiliser dans votre méthode d'extension. –

+0

J'ajouterais probablement une vérification nulle à ce code puisque Identity pourrait ne pas exister à tout moment, disons pendant les tests unitaires, et s'il est appelé dans un scénario de test, il vaut mieux ignorer le bloc Selected = true que de lancer une exception . –

0

Vous pouvez placer cette logique dans un BaseController (abstrait) puis en déduire tous vos contrôleurs et les faire appeler une méthode dans le BaseController pour obtenir ces données si nécessaire.

Si vous devez l'inclure dans ALL vos actions de contrôleur, vous pouvez également le placer dans un OnActionExecuting() surchargé dans le BaseController.

1

Mettez ce code, ou une partie du code dans une classe séparée - appelons-le UserService. Laissez UserService mettre en œuvre IUserService:

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

Injecter IUserService dans votre contrôleur par injection Constructor:

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

Utilisez le champ userService dans vos actions de contrôleur pour obtenir les utilisateurs.

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

Bien que je sois d'accord sur le fait que c'est un bon design, je ne suis pas vraiment sûr qu'il a besoin d'un service complet créé pour cela quand c'est vraiment juste une opération de conversion de type. –

+0

J'aime cette solution aussi. J'ai déjà un IUserService donc cela irait bien. – alexn