In this post we are going to see how to create a custom configuration section in web.config file or app.config file using c#, for that first we have to decide what kind of format that xml will going to look like , then only we can create element based on that, now for this post let we see , what kind of format we are trying to achieve.
Configuration are used to give the values for software during runtime. below is the structure we are going to build now.
<ComConfig name="development">
<Companies>
<Company name="Microsoft">
<Address street="RF street" city="Manhat" state="NYC" country="US" />
<Projects>
<Project name="C#">
<Developers>
<Developer name="Rajesh" designation="Architect" />
<Developer name="Suresh" designation="Tech Lead" />
</Developers>
</Project>
<Project name="VisualStudio">
<Developers>
<Developer name="Ramu" designation="Senior Developer" />
<Developer name="Appu" designation="Project Lead" />
</Developers>
</Project>
</Projects>
</Company>
<Company name="Google">
<Address street="GH street" city="Ledts" state="Pollis" country="US" />
<Projects>
<Project name="Android">
<Developers>
<Developer name="Chris" designation="Architect" />
<Developer name="Xing" designation="Project Lead" />
</Developers>
</Project>
<Project name="gmail">
<Developers>
<Developer name="Xander" designation="Senior Developer" />
<Developer name="Palo" designation="Tech Lead" />
</Developers>
</Project>
</Projects>
</Company>
</Companies>
</ComConfig>
from the above structure you can see lot of elements are there, some of them are collections, some of them are attributes.
For create a custom configuration element we need to derive the class from the ConfigurationElement and we have to define the property with ConfigurationProperty attribute.
public class CompanyElement : System.Configuration.ConfigurationElement
{
[ConfigurationProperty("name", IsRequired = true)]
public string Name
{
get { return (string)base["name"]; }
}
}
For define the customElement collection , we are defining a generic class, instead of creating collection class for each and every element , we are creating a generic class
Generic element collection:
public class ConfigurationElementCollection<T> : ConfigurationElementCollection,
IEnumerable<T> where T : ConfigurationElement, new()
{
List<T> _elementCollection = new List<T>();
protected override ConfigurationElement CreateNewElement()
{
T elem = new T();
_elementCollection.Add(elem);
return elem;
}
protected override object GetElementKey(ConfigurationElement element)
{
return _elementCollection.Find(x => x.Equals(element));
}
public T this[int index]
{
get
{
T ele = default(T);
if (index < _elementCollection.Count)
{
ele = _elementCollection[index];
}
return ele;
}
}
IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
return _elementCollection.GetEnumerator();
}
}
How to use:
[ConfigurationProperty("Developers",IsRequired =true)]
[ConfigurationCollection(typeof(DeveloperElement),AddItemName ="Developer",
RemoveItemName ="RemoveDeveloper",ClearItemsName ="ClearDeveloper")]
public ConfigurationElementCollection<DeveloperElement> Developers
{
get
{
return (ConfigurationElementCollection<DeveloperElement>)base["Developers"];
}
}
Above is sample how we have to declare the collection of an element
Here we have to create element for the four elements :- Company, Address, Project, Developer
Element Collection : Companies, Projects, Developers using Generic one
ConfigurationManager : ConfigurationSection
Next step is Declaration of configuration section in Configuration file, then add the configuration
Now let we see the implementation of each and every part one by one : first let we create each and every element finally we will creation section.
DeveloperElement
public class DeveloperElement:ConfigurationElement
{
[ConfigurationProperty("name",IsRequired =true)]
public string Name
{
get { return (string)base["name"]; }
}
[ConfigurationProperty("designation",IsRequired =true)]
public string Designation
{
get { return (string)base["designation"]; }
}
}
ProjectElement
public class ProjectElement : ConfigurationElement
{
[ConfigurationProperty("name",IsRequired =true)]
public string Name
{
get
{
return (String)base["name"];
}
}
[ConfigurationProperty("Developers",IsRequired =true)]
[ConfigurationCollection(typeof(DeveloperElement),AddItemName ="Developer",
RemoveItemName ="RemoveDeveloper",ClearItemsName ="ClearDeveloper")]
public ConfigurationElementCollection<DeveloperElement> Developers
{
get
{
return (ConfigurationElementCollection<DeveloperElement>)base["Developers"];
}
}
}
AddressElement
public class AddressElement : ConfigurationElement
{
[ConfigurationProperty("street", IsRequired = true)]
public string street
{
get { return (string)base["street"]; }
}
[ConfigurationProperty("city", IsRequired = true)]
public string city
{
get { return (string)base["city"]; }
}
[ConfigurationProperty("state", IsRequired = true)]
public string state
{
get { return (string)base["state"]; }
}
[ConfigurationProperty("country", IsRequired = true)]
public string country
{
get { return (string)base["country"]; }
}
}
CompanyElement
public class CompanyElement : ConfigurationElement
{
[ConfigurationProperty("name", IsRequired = true)]
public string Name
{
get { return (string)base["name"]; }
}
[ConfigurationProperty("Address", IsRequired = true)]
public AddressElement Address
{
get { return (AddressElement)base["Address"]; }
}
[ConfigurationProperty("Projects",IsRequired =true)]
[ConfigurationCollection(typeof(ProjectElement),AddItemName ="Project",
ClearItemsName ="ClearProject",RemoveItemName ="RemoveProject")]
public ConfigurationElementCollection<ProjectElement> Projects
{
get
{
return (ConfigurationElementCollection<ProjectElement>)base["Projects"];
}
}
}
Finally we will create configuration section
namespace COMConfig
{
public class ConfigurationManager: System.Configuration.ConfigurationSection
{
public static ConfigurationManager settings = (ConfigurationManager)
System.Configuration.ConfigurationManager.GetSection("ComConfig");
public static ConfigurationManager AppSettings
{
get
{
return settings;
}
}
[System.Configuration.ConfigurationProperty("name",IsRequired =true,IsKey =true)]
public string Name
{
get
{
return (string)base["name"];
}
}
[System.Configuration.ConfigurationProperty("Companies", IsRequired = true)]
[System.Configuration.ConfigurationCollection(typeof(CompanyElement),
AddItemName ="Company", ClearItemsName = "ClearCompany",
RemoveItemName = "RemoveCompany")]
public ConfigurationElementCollection<CompanyElement> Companies
{
get
{
return (ConfigurationElementCollection<CompanyElement>)base["Companies"];
}
}
}
}
Declaration of Section in configuration
The name which is declared in the name of the section should be the starting element, type should be specified along with namespace , assembly ... Give this info correctly , because sometimes you may forget to mention the assembly name correctly for example here ConfigSample is assembly name
Note : whatever element you define in xml file must have element declaration in code.
<configSections>
<section name="ComConfig" type="COMConfig.ConfigurationManager, ConfigSample"/>
</configSections>
Full configuration File:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="ComConfig" type="COMConfig.ConfigurationManager, ConfigSample"/>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6" />
</startup>
<ComConfig name="development">
<Companies>
<Company name="Microsoft">
<Address street="RF street" city="Manhat" state="NYC" country="US" />
<Projects>
<Project name="C#">
<Developers>
<Developer name="Rajesh" designation="Architect" />
<Developer name="Suresh" designation="Tech Lead" />
</Developers>
</Project>
<Project name="VisualStudio">
<Developers>
<Developer name="Ramu" designation="Senior Developer" />
<Developer name="Appu" designation="Project Lead" />
</Developers>
</Project>
</Projects>
</Company>
<Company name="Google">
<Address street="GH street" city="Ledts" state="Pollis" country="US" />
<Projects>
<Project name="Android">
<Developers>
<Developer name="Chris" designation="Architect" />
<Developer name="Xing" designation="Project Lead" />
</Developers>
</Project>
<Project name="gmail">
<Developers>
<Developer name="Xander" designation="Senior Developer" />
<Developer name="Palo" designation="Tech Lead" />
</Developers>
</Project>
</Projects>
</Company>
</Companies>
</ComConfig>
</configuration>
How we are going to access the created configuration
Now see the code how we are going to access the values from this element.
ConfigurationManager coll = ConfigurationManager.AppSettings;
foreach (CompanyElement item in coll.Companies)
{
Console.WriteLine("\n");
Console.WriteLine("\tCompany Name : " + item.Name);
Console.WriteLine(string.Format("\tAddress {0}, {1}, {2}, {3}",
item.Address.street,item.Address.city,
item.Address.state,item.Address.country));
foreach (ProjectElement proj in item.Projects)
{
Console.WriteLine("\n");
Console.WriteLine("\t\tProject Name : " + proj.Name);
foreach (DeveloperElement dev in proj.Developers)
{
Console.WriteLine(string.Format("\t\t\tDeveloper Name : {0},
Designation {1}", dev.Name, dev.Designation));
}
}
}
Console.Read();
Output :
From this post you can see how to create a custom configuration section for App.config or Web.config using C#.