4. Configuration Types

4.1 Ini Files

Nini has a built in INI parser written in 100% C#. This means that unlike other INI parsers it will run on any .NET platform, not just those running Windows. In addition the parser is written for flexibility, that is why it has support for multiple INI file types. The currently supported file types are as follows:

Case Sensitivity

The IniConfigSource class has a property that allows values to be case insensitive. This might be desirable for people upgrading their software from systems using the old Win32 API GetPrivateProfileString function which was not case sensitive. Here is an example of how to use it:

; Note the Load method is just an alternative to passing the file name
; to the constructor. 
IConfigSource source = new IniConfigSource();
source.Load("MyApp.ini");
source.CaseSensitive = false;

4.2 XML Files

Nini has it's own XML configuration file structure. It provides more flexibility than does the .NET configuration file format. It's main advantages are that you can have more than one XML configuration file and that the format is much more concise. Here is an example of the format. You will notice that it resembles an INI file quite closely. The configuration values are the same as the INI in the previous examples:

<!-- MyApp.xml -->
<Nini>
    <Section Name="Logging">
        <Key Name="File Name" Value="MyApp.log" />
        <Key Name="MessageColumns" Value="5" />
        <Key Name="MaxFileSize" Value="40000000000000" />
    </Section>
</Nini>

To load the file is very simple:

// Loads the XML file
XmlConfigSource source = new XmlConfigSource("MyApp.xml");
// Retrieves a value
long maxFileSize = source.Configs["Logging"].GetLong("MaxFileSize");
Here is the example in VB:
' Loads the XML file
Dim source As New XmlConfigSource("MyApp.xml")
' Retrieves a value
Dim maxFileSize As Long = source.Configs("Logging").GetLong("MaxFileSize")

4.3 Windows Registry Configuration

If you are using one of the many Microsoft Windows operating systems then you can access data from the Windows Registry. Here is an example key path for a registry item:
HKEY_LOCAL_MACHINE\Sofware\MyApp\Logging
"File Name"       "MyApp.log"  REG_SZ
"MessageColumns"  "5"          REG_DWORD
"MaxFileSize"     "40000000"   REG_DWORD

To access this code the method is a bit more complex than others. You must create a mapping to a registry entry. This functionality will also give you the ability to merge many registry keys into a single IConfigSource. Here is some example code to access it.

Here is an example in C#:
using Microsoft.Win32;
RegistryConfigSource source = new RegistryConfigSource();
// Loads the registry tree
source.AddMapping(Registry.LocalMachine, "Software\\MyApp\\Logging");
// Retrieves a value
long maxFileSize = source.Configs["Logging"].GetLong("MaxFileSize");
Here is the example in VB:
Imports Microsoft.Win32
Dim source As New RegistryConfigSource()
' Loads the registry tree
source.AddMapping(Registry.LocalMachine, "Software\\MyApp\\Logging")
' Retrieves a value
Dim maxFileSize As Long = source.Configs("Logging").GetLong("MaxFileSize")

If you'd like to recursively retrieve all data under a specified registry key there is a method to accomplish this as well.

If you want to get all subkeys underneath a key with a flat name you can do this:
using Microsoft.Win32;
// Loads the registry tree and all nodes beneath it without 
RegistryConfigSource source = new RegistryConfigSource();
source.AddMapping(Registry.LocalMachine, "Software\\MyApp", RegistryRecurse.Flattened);

string maxFileSize = source.Configs["MyApp"].GetString("SomeConfig");
long maxFileSize = source.Configs["Logging"].GetLong("MaxFileSize");
Here is the example in VB:
Imports Microsoft.Win32
' Loads the registry tree and all nodes beneath it without 
Dim source As New RegistryConfigSource()
source.AddMapping(Registry.LocalMachine, "Software\\MyApp", RegistryRecurse.Flattened)

Dim maxFileSize As String = source.Configs("MyApp").GetString("SomeConfig");
Dim maxFileSize As Long = source.Configs("Logging").GetLong("MaxFileSize")

4.4 .NET Configuration Files

The .NET Framework has it's own configuration file mechanism that uses a specific XML format. You may be familiar with them in ASP.NET as web.config files. If you are using them with Windows Forms, console applications, or services you will know them as [APP NAME].exe.config files. To support users that still use this configuration file format in their applications Nini has support for these files as well.

<!-- ExampleApp.exe.config -->
<configuration>
    <configSections>
        <section name="Logging" type="System.Configuration.NameValueSectionHandler" />
    </configSections>
    <Logging>
        <add key="File Name" value="MyApp.log" />
        <add key="MessageColumns" value="5" />
        <add key="MaxFileSize" value="40000000000000" />
    </Logging>
</configuration>
Accessing the data is very similar to loading an INI or XML file:
IConfigSource source = new DotNetConfigSource(DotNetConfigSource.GetFullConfigPath());

string fileName = source.Configs["Logging"].Get("File Name");
int columns = source.Configs["Logging"].GetInt("MessageColumns");
long fileSize = source.Configs["Logging"].GetLong("MaxFileSize");
Here is the example in VB:
Dim source As New DotNetConfigSource(DotNetConfigSource.GetFullConfigPath())

Dim fileName As String = source.Configs("Logging").Get("File Name")
Dim columns As Integer = source.Configs("Logging").GetInt("MessageColumns")
Dim fileSize As Long = source.Configs("Logging").GetLong("MaxFileSize")

4.5 Command Line (Argv) Configuration

Since the beginning of programming applications have had the capability to accept command line switches. These switches are simply strings passed into the application when it is first started. The Windows program Xcopy has many command line switches and the excellent downloading application wget has it's own switches as well. If you want to read a little more about how command line parameters work in .NET click here. Our first example is very similar to the others you have seen so far. The difference is that the AddSwitch method needs to be called for each configuration key. There is a short key and a long key that both can be used to fetch configuration data.

Here is an example in C#:
public static int Main(string[] args)
{
   ArgvConfigSource source = new ArgvConfigSource(args);

   source.AddSwitch("Logging", "file-name", "f");
   source.AddSwitch("Logging", "columns", "c");
   source.AddSwitch("Logging", "max-file-size", "m");

   if(args.Length > 0)
   {
      string fileName = source.Configs["Logging"].Get("file-name");
      int columns = source.Configs["Logging"].GetInt("columns");
      long fileSize = source.Configs["Logging"].GetLong("max-file-size");
   }
}
Here is the example in VB:
Public Static Function Main(args() As String) As Integer
   Dim source As New ArgvConfigSource(args)

   source.AddSwitch("Logging", "file-name", "f")
   source.AddSwitch("Logging", "columns", "c")
   source.AddSwitch("Logging", "max-file-size", "m")

   If (args.Length > 0) Then
      Dim fileName As String = source.Configs("Logging").Get("file-name")
      Dim columns As Integer = source.Configs("Logging").GetInt("columns")
      Dim fileSize As Long = source.Configs("Logging").GetLong("max-file-size")
   End If
End Function