How can I extract the code repetition here?
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 IAimsAndObje开发者_C百科ctivesPresenter) && IsLoggedIn; }
}
Use Generics
private bool SomeFuncName<T>()
{
return !(CurrentPresenter is T) && IsLoggedIn;
}
usage:
public bool CanGotoGotoAimsAndObjectives {
get { return SomeFuncName<IAimsAndObjectivesPresenter>(); }
}
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.
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.
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...
精彩评论