How to create your own custom configuration source in Asp.Net vNext
One of the new feature in Asp.Net vNext is that we can specify one or several configuration sources, a source where our application configuration is located, for example the old web.config (Xml format), JSON, ini or we can create our own custom configuration source, for example reading configurations from a database or other kind of format. In this blog post I will show you how we can create our own configuration source and use it in the Asp.Net vNext.
Setup configuration
In Asp.Net vNext we have the startup.cs file, it’s where we configure our middleware and our services to use.
public class Startup
{
public void Configure(IBuilder app)
{
}
}
The Startup file has a Configure method that takes an IBuilder as an argument. If you are familiar to create an OWIN host, you will see that the configuration concept is quite similar. With the Configure method we can setup our configuration, for example using Json or Ini etc:
public class Startup
{
public void Configure(IBuilder app)
{
var config = new Configuration().AddJsonFile("config.json")
.AddIniFile("config.ini");
}
}
We can setup several configuration sources, and the Configuration object will get configuration data from all the sources. To add our own custom source we need to create a class that implements the IConfigurationSource interface located in the namespace Microsoft.Framework.ConfigurationModel. The following is a simple example of a custom configuration source using a NameValueCollection:
public class MyConfigurationSource : IConfigurationSource
{
private NameValueCollection _config = new NameValueCollection();
public MyConfigurationSource()
{
}
public void Load()
{
_config.Add("mycustomdata", "My Value");
}
public IEnumerable<string> ProduceSubKeys(IEnumerable<string> earlierKeys, string prefix, string delimiter)
{
throw new NotImplementedException();
}
public void Set(string key, string value)
{
throw new NotImplementedException();
}
public bool TryGet(string key, out string value)
{
value = _config[key];
return true;
}
}
The Load method will contain the code to load configuration data, can for example be from a database, or other kind of sources. In this example I just add a key/value to a NamedValueCollection. Then in the TryGet method I simply assume the key someone tries to get is added to my collection, so I simply return true and set the value. Normally this method should of course try to get the value in a proper way. Now when my simple custom configuration source is in place I need to configure the use of it. This is done in the Startup.cs file and by using the Configuraiton class’s Add method:
public class Startup
{
public void Configure(IBuilder app)
{
var config = new Configuration();
config.Add(new MyConfigurationSource());
}
}
We can also create our own extension method so get a nicer way to add our configuration source by extending the IConfigurationSourceContainter.
public static class MyConfigurationSourceContainerExtension
{
public static IConfigurationSourceContainer AddMyCustomConfig(
this IConfigurationSourceContainer sourceContainer)
{
sourceContainer.Add(new MyConfigurationSource());
return sourceContainer;
}
}
Note: To not break the fluent configuration of the way to add configuration source we need to return the IConfigurationSourceContatiner.
Now we can use the extension like this:
public class Startup
{
public void Configure(IBuilder app)
{
var config = new Configuration().AddMyCustomConfig();
}
}
To get the data from our configuration source we can use the Configuration class’s Get method, the key I have added to the source is “mycustomdata”. The following code gets the value of the “mycustomdata”:
public class Startup
{
public void Configure(IBuilder app)
{
var config = new Configuration().AddMyCustomConfig();
var value = config.Get("mycustomdata");
}
}
Simple summary ;)
So by implementing the IConfigurationSource, we can create our own source for our application configuration.
If you want to know when I will post a blog post, please feel free to follow me on twitter @fredrikn