2009-12-14 1 views
4

J'essaie d'extraire le motif de code commun ici dans une méthode d'extraction, mais j'ai du mal à trouver le type approprié pour le type de Presenter. De l'aide?Comment puis-je extraire la répétition de code ici?

public bool CanGotoHome 
{ 
    get { return !(CurrentPresenter is IHomePresenter) && IsLoggedIn; } 
} 
public bool CanGotoImportanceOfAimsAndObjectives 
{ 
    get { return !(CurrentPresenter is IImportanceOfAimsAndObjectivesPresenter) && IsLoggedIn; } 
} 
public bool CanGotoGotoAimsAndObjectives 
{ 
    get { return !(CurrentPresenter is IAimsAndObjectivesPresenter) && IsLoggedIn; } 
} 
+0

btw, je voudrais vérifier IsLoggedIn d'abord et seulement après cela - vérifier le type. – abatishchev

Répondre

13

Utilisez Generics

private bool SomeFuncName<T>() 
{ 
    return !(CurrentPresenter is T) && IsLoggedIn; 
} 
utilisation

:

public bool CanGotoGotoAimsAndObjectives { 
    get { return SomeFuncName<IAimsAndObjectivesPresenter>(); } 
} 
+1

Un bon nom de fonction dans ce cas serait CanGoTo, ce qui donnerait return CanGoTo (); –

+0

@Luke, Merci pour l'aide de la syntaxe, @Darko, bonne idée pour le nom de la méthode. :) –

+0

aucun problème. Sur une autre note, n'aimez-vous pas les downvotes aléatoires? –

1

Ce code semble étrange en général ... S'il n'y a que ces 3 lignes, pourquoi prendre la peine de créer une méthode générale pour factoriser leur? Ça ne va pas vous épargner autant de répétitions. OTOH, s'il y en a plus, alors ce code ressemble à des requêtes/permissions typiques. Si vous avez plus de 3 types et que ces fonctions peuvent devenir plus complexes dans d'autres cas, pourquoi ne pas simplement les charger dans une table de base de données presenter_capabilities (ou même AD, si vous êtes dans un système d'entreprise ...)? Vérifiez si «la sécurité basée sur les capacités» n'est pas ce que vous recherchez vraiment.

En ce qui concerne le code lui-même, j'aller pour quelque chose comme:

public bool GetCapability(Caps cap) { 
    return IsLoggedIn && CapabilityResolver.Check(CurrentPresenter, cap); 
    // or even 
    // return CapabilityResolver.Check(CurrentPresenter, cap, IsLoggedIn); 
} 

// usage 
whatever.GetCapability(Caps.CanGoHome); 

vous épargnerez de recompiler si les règles deviennent plus compliquées, ou si vous ajoutez de nouveaux caps/interfaces. Si elles sont à peu près statiques, vous pouvez simplement les résoudre à l'aide d'un hash.

+0

Merci pour vos deux cents, je réfléchirai à ce sujet. –

1

Sur la base de l'exemple de code, je serais un peu tenté d'utiliser les définitions principales/rôle encastrables ici, et quelques constantes de chaîne:

static bool IsInRole(string role) { 
    if (string.IsNullOrEmpty(role)) return true; 
    IPrincipal principal = Thread.CurrentPrincipal; 
    return principal == null ? false : principal.IsInRole(role); 
} 
public bool CanGotoHome 
    get { IsInRole(AccessRights.GotoHome); } 
} 

bien que peut-être ce que se déplace la responsabilité de créer une mesure appropriée principal ...

2

Pour moi, il semblerait plus facile si l'objet savait juste comment il devrait agir.

class BasePresenter 
{ 
    public bool CanGotoHome 
    { 
     get { return IsLoggedIn; } 
    } 
} 

class HomePresenter : BasePresenter 
{ 
    public bool CanGotoHome 
    { 
     get { return False; } 
    } 
} 

Ensuite, faites de même pour les autres méthodes. Cela semble beaucoup plus simple et plus clair.

Questions connexes