In our software we enable certain features based on the existence of a flag in the Windows Registry. We have a global method called FeatureIsEnabled(string propertyName)
that checks the registry for a particular feature name, which is hard-coded in the software.
I came across one piece of logic that I wrote that I feel could benefit from refactoring. The boolean logic works, but I think it's difficult to understand or read because it relies very heavily on short-circuiting.
The basic logic is:
- Get all menu items.
- Return a subset of those menu items by using the following rule:
- Some menu items are tied to a specific enable-able feature. We check whether a feature is enabled in the registry by calling
FeatureIsEnabled(string featureName)
. - Any other menu items by default are enabled, and should be displayed.
- Some menu items are tied to a specific enable-able feature. We check whether a feature is enabled in the registry by calling
Any help would be much appreciated.
private IEnumerable<MenuItemDefinition> GetMenuItems()
{
return GetAllMenuItems().Where(mi =>
(mi.MethodName != "NewWidget" || FeatureIsEnabled("Widgets")) &&
(mi.MethodName != "DeleteWidget" || FeatureIsEnabled("Widgets")) &&
(mi.MethodName != "NewDongle" || FeatureIsEnabled("Dongles")) &&
(mi.MethodName != "DeleteDongle" || FeatureIsEnabled("Dongles")));
}
Update: Updated example code and further information
I updated the sample code to be a bit cleaner. Also, here is the sample result of a GetAllMenuItems()
call, which is processed by the code block above in GetMenuItems()
:
new []
{
new MenuItemDefinition() { MethodName = "NewWidget" },
new MenuItemDefinition() { MethodName = "DeleteWidget" },
new MenuItemDefinition() { MethodName = "Save" },
new MenuItemDefinition() { MethodName = "Close" },
new MenuItemDefinition() { MethodName = "NewDongle" },
new MenuItemDefinition() { MethodName = "DeleteDongle" }
}
If the feature "Dongles" is enabled, then the method should return Save, Close, NewDongle, and DeleteDongle.
The goal of refactoring GetMenuItems is to not rely on inlining a huge number of confusing boolean logic, and instead coming up with a construct that is easier to follow. Currently, have to explain to the casual observer the curious combination of the !=
, ||
, and &&
. I think a simpler method exists, I'm just not sure what.