Custom App.Config Section with a Simple List of "Add" Elements

Custom app.config section with a simple list of add elements

Full example with code based on OP config file:

<configuration>
<configSections>
<section name="registerCompanies"
type="My.MyConfigSection, My.Assembly" />
</configSections>
<registerCompanies>
<add name="Tata Motors" code="Tata"/>
<add name="Honda Motors" code="Honda"/>
</registerCompanies>
</configuration>

Here is the sample code to implement a custom config section with collapsed collection

using System.Configuration;
namespace My {
public class MyConfigSection : ConfigurationSection {
[ConfigurationProperty("", IsRequired = true, IsDefaultCollection = true)]
public MyConfigInstanceCollection Instances {
get { return (MyConfigInstanceCollection)this[""]; }
set { this[""] = value; }
}
}
public class MyConfigInstanceCollection : ConfigurationElementCollection {
protected override ConfigurationElement CreateNewElement() {
return new MyConfigInstanceElement();
}

protected override object GetElementKey(ConfigurationElement element) {
//set to whatever Element Property you want to use for a key
return ((MyConfigInstanceElement)element).Name;
}
}

public class MyConfigInstanceElement : ConfigurationElement {
//Make sure to set IsKey=true for property exposed as the GetElementKey above
[ConfigurationProperty("name", IsKey = true, IsRequired = true)]
public string Name {
get { return (string) base["name"]; }
set { base["name"] = value; }
}

[ConfigurationProperty("code", IsRequired = true)]
public string Code {
get { return (string) base["code"]; }
set { base["code"] = value; }
} } }

Here is an example of how to access the configuration information from code.

var config = ConfigurationManager.GetSection("registerCompanies") 
as MyConfigSection;

Console.WriteLine(config["Tata Motors"].Code);
foreach (var e in config.Instances) {
Console.WriteLine("Name: {0}, Code: {1}", e.Name, e.Code);
}

Custom configuration section in app.config - XML attributes Vs elements

As far as i know, you can't place values in xml sections in app.config file while using ConfigurationManager

But you have a quite similar option to work with config structures like that:

<DataSourcesConfig>
<DataSources>
<DataSource>
<name value="test1"/>
<connectionType value="Ethernet_TCP_Client"/>
<protocolType value="Serial"/>
<ipAddress value="127.0.0.1"/>
<port value="12345"/>
</DataSource>
<DataSource>
<name value="test2"/>
<connectionType value="Ethernet_TCP_Client"/>
<protocolType value="Serial"/>
<ipAddress value="127.0.0.1"/>
<port value="12346"/>
</DataSource>
</DataSources>
</DataSourcesConfig>

First of all, you need to define an ValueElement:

public class ValueElement<T> : ConfigurationElement
{
[ConfigurationProperty("value", IsRequired = true)]
public T Value => (T) this["value"];
}

Next, change your DataSource element like that:

public class DataSource : ConfigurationSection // It is section now
{
[ConfigurationProperty("name", IsRequired = true)]
public ValueElement<string> Name => this["name"] as ValueElement<string>;

[ConfigurationProperty("connectionType", IsRequired = true)]
public ValueElement<string> ConnectionType => this["connectionType"] as ValueElement<string>;

[ConfigurationProperty("protocolType", IsRequired = true)]
public ValueElement<string> ProtocolType => this["protocolType"] as ValueElement<string>;

[ConfigurationProperty("ipAddress", IsRequired = true)]
public ValueElement<string> IPAddress => this["ipAddress"] as ValueElement<string>;

[ConfigurationProperty("port", IsRequired = true)]
public ValueElement<int> Port => this["port"] as ValueElement<int>;
}

Now you can use your config in code like that:

var configuration = DataSourcesConfig.GetConfig();
var test1name = configuration.DataSources[0].Name.Value; // test1 as string
var test2name = configuration.DataSources[1].Name.Value; // test2 as string
var portForTest1 = configuration.DataSources[0].Port.Value // 12345 as int

Custom app.config section error Unrecognized element add

I managed to get the following to work in a console app by adding a parent DatabaseConfig node:

The DatabaseFieldSection class:

public class DatabaseFieldSection : ConfigurationSection
{
public static DatabaseFieldSection GetConfig()
{
return (DatabaseFieldSection)System.Configuration.ConfigurationManager.GetSection("DatabaseConfig") ?? new DatabaseFieldSection();
}

[System.Configuration.ConfigurationProperty("DatabaseFields")]
[ConfigurationCollection(typeof(DatabaseFieldCollection), AddItemName = "add")]
public DatabaseFieldCollection DatabaseFields
{
get
{
object o = this["DatabaseFields"];
return o as DatabaseFieldCollection;
}
}
}

And the App.config:

<configSections>
<section name="DatabaseConfig" type="TestEnvironment.DBConfig.DatabaseFieldSection, TestEnvironment"/>
</configSections>
<DatabaseConfig>
<DatabaseFields>
<add Key="Person.FirstName (SV)" TableName="dbo.Person" ColumnName="FirstName" FieldType="SV" />
</DatabaseFields>
</DatabaseConfig>

Usage:

var config = DatabaseFieldSection.GetConfig();

It seems as though the config <section /> cannot be the same as the config element collection name. e.g DatabaseFields, it needs to be:

Section > Collection > Items

Or:

DatabaseConfig > DatabaseFields > add

How do I add custom ConfigurationSection to Assembly?

If I understand correctly, you have problem with resolving what actually your Assembly is, since you are only creating .cs files that determine types that this file hold.

Assembly (in maybe not so accurate shorcut) is just the project you have in your solution. It will get compiled into its seperate assembly - the .dll you mentioned - later on.
When you add class to any .cs file in given project, on compile it will be included in project's assembly.

By default, if you won't provide assembly for configSection where its corresponding type should be found, App.config defaults to System.Configuration assembly - that's where you get your error from, since you've declared your section in your own assembly (== project).

Right click in Visual Studio on your project that holds App.config file and choose Properties to check its Assembly name:

Sample Image

Then add this name to your App.config section declaration. In my example its ConsoleApp1, so I will add it to configuration accordingly:

<configSections>
<section name="testSection" type="mssql_gui.TestConfigSection, ConsoleApp1"/>
</configSections>

Can I parse app.config custom sections to List data structure?

The .NET Framework does support having lists of items in its configuration, but not quite as you have listed. If you look at the appSettings section of your file, you can see an example of a collection:

<appSettings>
<add key="foo" value="Fizz" />
<add key="bar" value="Buzz" />
</appSettings>

This is built on the specialised collection ConfigurationElementCollection which allows you to model add remove and clear functions as XML in order to build up your list of items.

First, mark the name property of the PersonConfiguration as the key. I'm assuming the name of the person is suitable as the key identifier; if you come up with a different identifier, use that.

[ConfigurationProperty("name", IsKey = true, IsRequired = true)]
public string Name
{
get { return (string)this["name"]; }
set { this["name"] = value; }
}

Create your custom collection deriving from ConfigurationElementCollection so you return the key value for a person.

[ConfigurationCollection(typeof(PersonConfiguration))]
public class PersonConfigurationElementCollection : ConfigurationElementCollection
{
protected override PersonConfiguration CreateNewElement()
{
return new PersonConfiguration();
}

protected override object GetElementKey(ConfigurationElement element)
{
return ((PersonConfiguration)element).Name;
}
}

Then add this collection to your custom configuration section's class:

public class MyCustomCongifuration : ConfigurationSection
{
[ConfigurationProperty("people", IsDefaultCollection = true)]
public PersonConfigurationElementCollection People
{
get { return (PersonConfigurationElementCollection)this["people"]; }
set { this["people"] = value; }
}
}

You can now create a collection of people as such:

<myCustomSection>
<people>
<add name="John" age="30" />
<add name="Mike" age="46" />
</people>
</muCustomSection>

If you want to turn that configuration collection to a list, you can use a little bit of Linq:

var configuration = (MyCustomConfiguration)ConfigurationManager
.GetSection("myCustomSection");
var people = configuration.People.Cast<PersonConfiguration>().ToList();

Custom config section in app.config with common elements to iterate

You can use GetSection method on AppSettings. Example code on MSDN for that methd has example on how to get the raw XML for the section, which you can then iterate as XML.

https://msdn.microsoft.com/en-us/library/system.configuration.configurationmanager.getsection%28v=vs.110%29.aspx

What is type in App.config custom section

If the Project name is "My". It works with this config. After 3 hours I found a solution :)

 <?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="registerCompanies"
type="My.MyConfigSection, My" />
</configSections>
<registerCompanies>
<add name="Tata Motors" code="Tata"/>
<add name="Honda Motors" code="Honda"/>
</registerCompanies>
</configuration>


Related Topics



Leave a reply



Submit