4

Is there a way to set multiple enum values in a configuration section?

Like you do in .net object.Filter = Filter.Update | Filter.Create;

<wacther filter="update, created"/>

Is something like that supported?

mimo
  • 937
  • 12
  • 19

3 Answers3

10

It just works out of the box:

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            var section = (MySection)ConfigurationManager.GetSection("mySection");
            Console.WriteLine(section.Enum);
        }
    }

    public class MySection : ConfigurationSection
    {
        [ConfigurationProperty("enum")]
        public MyEnum Enum
        {
            get { return (MyEnum)this["enum"]; }
            set { this["enum"] = value; }
        }
    }

    [Flags]
    public enum MyEnum
    {
        None = 0,
        Foo = 1,
        Bar = 2,
        Baz = 4
    }
}


<configSections>
  <section name="mySection" type="ConsoleApplication1.MySection, ConsoleApplication1"/>
</configSections>

<mySection enum="Foo, Bar"/>

Prints: Foo, Bar

fsimonazzi
  • 2,975
  • 15
  • 13
  • 2
    Whoever uses this, please be aware that it will combine flags wherever possible, so if the logic above had Foz = 3 defined in MyEnum, and the config had flags, "Foo, Bar", it would parse that as Foz. – Alexandru Dec 17 '14 at 16:59
  • 1
    That wouldn't be an effect of the parsing, but how the numeric value is rendered. Both "MyEnum.Foo | MyEnum.Bar" and "MyEnum.Foz" would map to the same integral value "3", but when rendering it (e.g. when calling ToString()) the best match will be chosen. See the notes in http://msdn.microsoft.com/en-us/library/16c1xs4z%28v=vs.110%29.aspx – fsimonazzi Dec 17 '14 at 18:40
4

Define a flag enum:

[Flags]
enum Filter
{
    None = 0,
    Update = 1,
    Create = 2
}

Assume you have a string of enum from your config file:

var enumString = "update, create";

So you can get the result:

var result = (Filter) Enum.Parse(typeof (Filter), enumString, true);
cuongle
  • 74,024
  • 28
  • 151
  • 206
  • 1
    I see several issues with the approach. a) The platform already provides support, there is no need to replicate the functionality b) Problems parsing the values are associated to the location in the file when the framework does the parsing c) The approach requires you to parse the flat string into individual tokens, so it's not a complete solution, and Enum.Parse already deals with several comma separated values for flag enums so there's no need for a split. – fsimonazzi Nov 01 '12 at 16:06
  • @fsimonazzi: thanks for your comment, option C is valuable, I am not sure I am understand the option A and B from you – cuongle Nov 01 '12 at 16:23
  • They are not really options but issues with the approach. Why do something when the platform already does it for you, and it does a better job because it doesn't force you to deal with strings (you only declare the enum and System.Configuration does the parsing), and in case of a parsing error it will indicate exactly where in the configuration file is the offending content. I just see no reason for not letting the framework deal with this, and in fact the original question was whether this scenario was supported; the answer is yes. – fsimonazzi Nov 01 '12 at 16:32
  • @fsimonazzi: Well, think about, this enum values can put somewhere, config file (AppSettings for example), or even other file. Using one Section like yours seems over complicated. – cuongle Nov 02 '12 at 02:59
  • The original poster already has a configuration section and wants to know how to set a property with multiple enum values. The sample XML shows a custom "watcher" configuration element with a custom "filter" configuration property. The code I've included just shows that the parsing of flag enums works. Of course it would be overkill as a solution if you wanted to store a discrete setting in the configuration file, but that was not what was asked. – fsimonazzi Nov 02 '12 at 12:09
0

The easiest way is to use FlagsAttribute. But if you have already had the enum with the set of values, then you can use this code:

public static IEnumerable<T> GetEnumValues<T>(string enumValues)
{
    return string.IsNullOrEmpty(enumValues)
        ? Enumerable.Empty<T>()
        : enumValues.Split(',').Select(e => System.Enum.Parse(typeof(T), e.Trim(), true)).Cast<T>();
}

[ConfigurationProperty("filter")]
public string Filter => GetEnumValues<FilterEnum>((string) this["filter"]);
Moch Yusup
  • 1,266
  • 14
  • 14