0

I used code from this post to implement feature toggles in an application and it is working great. However, now instead of my features being a straight bool on/off, each feature has two bool values: one for the general setting and one for the setting which is only applied to a subset of users. I've been trying to update the code to handle this and I'm finding my basic understanding of reflection and accessors is coming up short.

I'm using the code below to test in LINQPad - basically, compared to the post mentioned above, all I've done is tried to change TestFeatureToggle from a bool, to type MultiToggle but I'm struggling to Set or Get the value of the bool properties of the MultiToggle object. I get an exception at

return (bool)multiToggleProperty.GetValue(null,null); 

"Non-static method requires a target". Which makes sense because the properties on MultiToggle are non-static. However, I don't have an instance of those objects and I don't understand how I would get one from a static class.

Any help would be really appreciated. My gut says it might not be possible!

 void Main() { var exampleFeatureToggles = new List<FeatureToggle> { new FeatureToggle {Description = "Test", Id = 1, IsActive = true, Name = "TestFeatureToggle"} }; FeatureToggles.SetFeatureToggles(exampleFeatureToggles); Console.WriteLine(FeatureToggles.GetFeatureToggleSetting("TestFeatureToggle")); } public class FeatureToggle { public string Description { get; set; } public int Id { get; set; } public bool IsActive { get; set; } public string Name { get; set; } } public class MultiToggle { public bool DefaultValue { get; private set; } public bool OtherValue { get; private set; } } public static class FeatureToggles { //public static bool TestFeatureToggle { get; private set; } public static MultiToggle TestFeatureToggle { get; private set; } public static void SetFeatureToggles(List<FeatureToggle> toggles) { if (toggles == null) return; var properties = typeof(FeatureToggles).GetProperties(BindingFlags.Public | BindingFlags.Static); // All properties must be set to false to prevent a property staying true when deleted from the database foreach (var property in properties) { var multiToggleProperties = typeof(MultiToggle).GetProperties(); foreach (var multiToggleProperty in multiToggleProperties) { multiToggleProperty.SetValue(new MultiToggle(), false, null); } } foreach (var toggle in toggles) { foreach (var property in properties) { if (property.Name.ToLower() == toggle.Name.ToLower()) { Type tProp = property.GetType(); var multiToggleProperties = typeof(MultiToggle).GetProperties(); foreach (var multiToggleProperty in multiToggleProperties) { Console.WriteLine(multiToggleProperty); multiToggleProperty.SetValue(new MultiToggle(), toggle.IsActive, null); } } } } } public static bool GetFeatureToggleSetting(string propertyName) { var properties = typeof(FeatureToggles).GetProperties(BindingFlags.Public | BindingFlags.Static); foreach (var property in properties) { if (property.Name.ToLower() == propertyName.ToLower()) { Type tProp = property.GetType(); var multiToggleProperties = typeof(MultiToggle).GetProperties(); Console.WriteLine(multiToggleProperties); foreach (var multiToggleProperty in multiToggleProperties) { Console.WriteLine(multiToggleProperty); return (bool)multiToggleProperty.GetValue(null, null); } } } return false; } } 
1
  • I think return (bool)multiToggleProperty.GetValue(null, null) should be return (bool)multiToggleProperty.GetValue(tProp.GetValue(null, null), null); because you have to get the values of the MultiToggle properties from an actual MultiToggle instance. In this case your static "TestFeatureToggle" property. Also in the Set-method you're not actually setting anything on TestFeatureToggle, you're just instantiating new MultiToggle instances which won't be stored anywhere. Commented Feb 2, 2016 at 17:35

1 Answer 1

1

The idea was there but you've essentially "just overshot the mark". You are getting the "Non-static method requires a target" error because you are trying to get the value of a property in the value of a static property, without getting the value of the static property first (what a mouthful). i.e. you are going:

get static property type -> get instance property type -> get value of property from static property. 

DefaultValue, and OtherValue are instance properties so you will need the instance object first before you can get their value. I made a few tweaks just to show you how to both set the static property and get the values from the static property. You should be able to tweak it from there:

void Main() { var exampleFeatureToggles = new List<FeatureToggle> { new FeatureToggle {Description = "Test", Id = 1, IsActive = true, Name = "TestFeatureToggle"} }; FeatureToggles.SetFeatureToggles(exampleFeatureToggles); Console.WriteLine(FeatureToggles.GetFeatureToggleSetting("TestFeatureToggle")); } public class FeatureToggle { public string Description { get; set; } public int Id { get; set; } public bool IsActive { get; set; } public string Name { get; set; } } public class MultiToggle { public bool DefaultValue { get; private set; } public bool OtherValue { get; private set; } } public static class FeatureToggles { //public static bool TestFeatureToggle { get; private set; } public static MultiToggle TestFeatureToggle { get; private set; } public static void SetFeatureToggles(List<FeatureToggle> toggles) { if (toggles == null) return; var properties = typeof(FeatureToggles).GetProperties(BindingFlags.Public | BindingFlags.Static); // All properties must be set to false to prevent a property staying true when deleted from the database foreach (var property in properties) { // first change: set the _property_, not multiToggleProperty property.SetValue(null, new MultiToggle()); } foreach (var toggle in toggles) { foreach (var property in properties) { if (property.Name.ToLower() == toggle.Name.ToLower()) { Type tProp = property.GetType(); var multiToggleProperties = typeof(MultiToggle).GetProperties(); // second change: create a nee instance, set the values, then set that value on the static property var newMultiToggle = new MultiToggle(); property.SetValue(null, newMultiToggle); foreach (var multiToggleProperty in multiToggleProperties) { Console.WriteLine(multiToggleProperty); multiToggleProperty.SetValue(newMultiToggle, toggle.IsActive, null); } } } } } public static bool GetFeatureToggleSetting(string propertyName) { var properties = typeof(FeatureToggles).GetProperties(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy); foreach (var property in properties) { if (property.Name.ToLower() == propertyName.ToLower()) { Type tProp = property.GetType(); // third change: get the static value first, then get the value from the properties on that instance. var value = property.GetValue(null); var multiToggleProperties = typeof(MultiToggle).GetProperties(); Console.WriteLine(multiToggleProperties); foreach (var multiToggleProperty in multiToggleProperties) { Console.WriteLine(multiToggleProperty); return (bool)multiToggleProperty.GetValue(value, null); // } } } return false; } } 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.