0

I'm coming from the Java world - and Java properties files can be built based on each other in the following manner...

base.dir=C:\dev\basedir
logging.dir=$(base.dir)\logs  # results in C:\dev\basedir\logs
output.dir=$(base.dir)\output # results in C:\dev\basedir\output

How can the same be accomplished in a .NET project using settings and the app.config file? I've spent a long time searching and found nothing that works yet...

The following approach in app.config does not work (returns the literal value)...

<setting name="baseDir" serializeAs="String">
   <value>C:\dev\basedir</value>
</setting>
<setting name="logDir" serializeAs="String">
   <value>$(baseDir)log\</value>
</setting>
Michael K
  • 439
  • 3
  • 13
  • What you're showing in the Java properties file isn't an inherent part of java.util.Properties... perhaps you're using something on top of them? – Jon Skeet Jul 03 '14 at 14:23
  • http://stackoverflow.com/questions/2400097/reading-from-app-config-file – Thomas Lindvall Jul 03 '14 at 14:24
  • @JonSkeet - Yes, using XProperties on top of java.util.Properties – Michael K Jul 03 '14 at 14:35
  • @ThomasLindvall - How is the link provided relevant to the question I am asking about building values on each other? – Michael K Jul 03 '14 at 14:36
  • Okay, so when you say "Java properties files" you mean "Java properties with a 3rd party library" - you could build a similar library for app.config yourself pretty easily, I suspect. – Jon Skeet Jul 03 '14 at 15:10

2 Answers2

0

I'm not familiar with a way to do this from within the app.config file. It would be fairly easy to write such functionality in your program, though.

<setting name="baseDir" serializeAs="String">
   <value>C:\dev\basedir</value>
</setting>
<setting name="logDir" serializeAs="String">
   <value>log\</value>
</setting>

Then, in your C#, you could combine them using the Path helper class. (Note, this is untested, I'm coding from memory on how the syntax works for the userSettings rather than appSettings).

System.IO.Path.Combine(Properties.Settings.Default.baseDir, 
    Properties.Settings.Default.logDir);
Cole Cameron
  • 2,213
  • 1
  • 13
  • 12
0

Providing a follow up answer to my own question...

Assuming a properties file that looks like this:

## Directories
base.dir=C:\PdfProcessing
archive.dir=${base.dir}\archive
manual.process.dir=${base.dir}\manual_process

The following class will parse the properties file into a map...

static class PropertiesFileReader
{
    private static string PathToPropertiesFile = @"application.properties";
    private static Regex subRegex = new Regex(@"\$\{.*\}");

    /// <summary>
    /// Parses the properties file into a map 
    /// </summary>
    /// <returns></returns>
    public static Dictionary<string, string> ReadProperties() {
        var data = new Dictionary<string, string>();

        foreach (var row in File.ReadAllLines(PathToPropertiesFile))
        {
            var newRow = String.Empty;

            // ignore any rows that are commented out
            // or do not contain an equals sign
            if (!row.StartsWith("#") && row.Contains("="))
            {
                // replace each instance of a variable placeholder in the property value
                foreach (Match match in subRegex.Matches(row))
                {
                    var key = Regex.Replace(match.ToString(), @"[${}]", String.Empty);
                    var replaceValue = data[key];
                    newRow = row.Replace(match.ToString(), replaceValue);
                }

                // add the property key and value
                if (!String.IsNullOrEmpty(newRow))
                {
                    data.Add(newRow.Split('=')[0], string.Join("=", newRow.Split('=').Skip(1).ToArray()));
                }
                else
                {
                    data.Add(row.Split('=')[0], string.Join("=", row.Split('=').Skip(1).ToArray()));
                }
            }


        }


        return data;

    }

}

Then call the reader this way...

private static readonly Dictionary<string, string> props = PropertiesFileReader.ReadProperties();

And access the property values this way...

props["archive.dir"] # C:\PdfProcessing\archive
Michael K
  • 439
  • 3
  • 13
  • 1
    adapted from @Luis Filipe (http://stackoverflow.com/questions/485659/can-net-load-and-parse-a-properties-file-equivalent-to-java-properties-class) – Michael K Jul 10 '14 at 13:45