Geeks With Blogs

News ASP.net Forms Justin Hoffman
Justin Hoffman

I wanted to try to use T4 to read a web.config and generate all of the appSettings and connectionStrings as properties of a class.  I elected in this template only to output appSettings and connectionStrings but you can see it would be easily adapted for app specific settings, bindings etc.  This allows for quick access to config values as well as removing the potential for typo's when accessing values from the ConfigurationManager. One caveat: a developer would need to remember to run the .tt file after adding an entry to the web.config.  However, one would quickly notice when trying to access the property from the generated class (it wouldn't be there).  Additionally, there are other options as noted here.

The first step was to create the .tt file.  Note that this is a basic example, it could be extended even further I'm sure.  In this example I just manually input the path to the web.config file.

<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ output extension=".cs" #>
<#@ assembly Name="System.Configuration" #>
<#@ assembly name="System.Xml" #>
<#@ assembly name="System.Xml.Linq" #>
<#@ assembly name="System.Net" #>
<#@ assembly name="System" #>
<#@ import namespace="System.Configuration" #>
<#@ import namespace="System.Xml" #>
<#@ import namespace="System.Net" #>
<#@ import namespace="Microsoft.VisualStudio.TextTemplating" #>
<#@ import namespace="System.Xml.Linq" #>



using System;
using System.Configuration;
using System.Xml;
using System.Xml.Linq;
using System.Linq;


namespace MyProject.Web
{
public partial class Configurator
{

<#
var xDocument = XDocument.Load(@"G:\MySolution\MyProject\Web.config");
var results = xDocument.Descendants("appSettings");
const string key = "key";
const string name = "name";
foreach (var xElement in results.Descendants())
{#>

public string <#= xElement.Attribute(key).Value#>{get {return ConfigurationManager.AppSettings[<#= string.Format("{0}{1}{2}","\"" , xElement.Attribute(key).Value, "\"")#>];}}

<#}#>

<#
var connectionStrings = xDocument.Descendants("connectionStrings");
foreach(var connString in connectionStrings.Descendants())
{#>
public string <#= connString.Attribute(name).Value#>{get {return ConfigurationManager.ConnectionStrings[<#= string.Format("{0}{1}{2}","\"" , connString.Attribute(name).Value, "\"")#>].ConnectionString;}}
<#} #>

}


}

The resulting .cs file:

using System;
using System.Configuration;
using System.Xml;
using System.Xml.Linq;
using System.Linq;


namespace MyProject.Web
{
public partial class Configurator
{


public string ClientValidationEnabled{get {return ConfigurationManager.AppSettings["ClientValidationEnabled"];}}


public string UnobtrusiveJavaScriptEnabled{get {return ConfigurationManager.AppSettings["UnobtrusiveJavaScriptEnabled"];}}


public string ServiceUri{get {return ConfigurationManager.AppSettings["ServiceUri"];}}


public string TestConnection{get {return ConfigurationManager.ConnectionStrings["TestConnection"].ConnectionString;}}
public string SecondTestConnection{get {return ConfigurationManager.ConnectionStrings["SecondTestConnection"].ConnectionString;}}

}


}

Next, I extended the partial class for easy access to the Configuration. However, you could just use the generated class file itself.

using System;
using System.Linq;
using System.Xml.Linq;

namespace MyProject.Web
{
public partial class Configurator
{
private static readonly Configurator Instance = new Configurator();

public static Configurator For { get { return Instance; } }

}
}

Finally, in my example, I used the Configurator class like so:

        [TestMethod]
public void Test_Web_Config()
{
var result = Configurator.For.ServiceUri;
Assert.AreEqual(result, "http://localhost:30237/Service1/");
}

 

Posted on Wednesday, March 2, 2011 8:56 AM | Back to top


Comments on this post: Using T4 to generate Configuration classes

# re: Using T4 to generate Configuration classes
Requesting Gravatar...
This is a really nice solution! However, it would be much better if it could be used to infer the type of the config value as well. In your example, everything is converted to a string, which is fine, but then it means that it needs re-casting. There's an example of somewhere that this has been done (albeit in VB due to IsNumeric) - http://stackoverflow.com/questions/1583642/auto-generate-an-application-facade-from-appsettings/3379723#3379723
Left by Dan Atkinson on Mar 07, 2011 4:42 AM

# re: Using T4 to generate Configuration classes
Requesting Gravatar...
Indeed, it would be much better. I thought about this but in my attempts I seemed to just be recreating what we already have in .settings files. Thanks for the reference, the solution noted there is interesting.
Left by Justin Hoffman on Mar 07, 2011 2:01 PM

Your comment:
 (will show your gravatar)


Copyright © Justin Hoffman | Powered by: GeeksWithBlogs.net