views:

162

answers:

4

I am trying to extract out the common code pattern here in an extract method, but am having trouble finding the proper type for the type of Presenter. Any help?

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; } 
}
+13  A: 

Use Generics

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

usage:

public bool CanGotoGotoAimsAndObjectives { 
    get { return SomeFuncName<IAimsAndObjectivesPresenter>(); } 
}
Luke Schafer
A good func name in this case would be CanGoTo, which would result inreturn CanGoTo<IHomePresenter>();
Darko Z
@Luke, Thanks for the syntax help, @Darko, good idea for method name. :)
Alex Baranosky
no probs.on another note, don't you love random downvotes?
Luke Schafer
@Luke, actually I do love them, because I always end up getting more rep when I am randomly downvoted, because people see it and upvote, which is then a net greater amount of rep for me :)
Alex Baranosky
hehe that's an amusing thought. On a side note, I hope my code works, I didn't test it :)
Luke Schafer
+1  A: 

This code looks strange in general... If there are only those 3 lines, why bother creating a general method to refactor them? It's not going to save you that much repetition.

OTOH, if there are more, then this code looks like typical capabilities / permission querying. If you have more than 3 types and those functions can get more complex in other cases, then why not just load those into a presenter_capabilities database table (or even AD, if you're in an enterprisey system...)? Check whether "Capability-based security" isn't what you're really looking for.

As for the code itself, I'd go for something like:

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

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

Saves you from recompiling if the rules get more complicated, or if you add any new caps / interfaces. If they are pretty much static, you can just resolve them through some hash.

viraptor
Thanks for your two cents, I'll reflect on it.
Alex Baranosky
+1  A: 

Based on the code sample, I would be a bit tempted to use the inbuilt principal / role definitions here, and some string constants:

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

although maybe this just shifts the responsibility to creating an appropriate custom principal...

Marc Gravell
+2  A: 

To me, it would seem easier if the object just knew how it should act.

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

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

And then do the same for the other methods. This seems much simpler and clearer.

unholysampler