C# 4.0 Dynamic programming to create a wrapper for reading appSettings section

By Indranil Chatterjee

This FAQ illustrates how to simplify the API to read configuration entries from appSettings section from a App.config or Web.config file using a wrapper created by C# 4.0 dynamic programming.

In many of our programs we have to read custom configuration entries (key/value) from appSettings section (or for that matter, any other section) from our App.config or Web.config files.
We access it using a syntax like:

ConfigurationManager.AppSettings["MyKey1"]

This has a few problems. Firstly, it requires us to use indexer syntax which involves more key strokes and it isn’t very neat either. If someone mistypes the key value, the compiler won’t complain until runtime.
What if we could use property syntax like AppSettings.MyKey1? It saves us a few key strokes and the syntax is more readable. But with the AppSettings property (which is a NameValueCollection), it isn’t possible as its entries can vary.
With dynamic programming constructs of C# 4.0, we can combine the flexibility of varying keys and the ease of property syntax. The C# dynamic library comes with a class DynamicObject. This class allows one to override operations like getting/setting a property/member, invoking a method, conversion, accessing indexers and others.
Let’s create a wrapper for the appSettings section as follows:

public class AppSettingsWrapper : DynamicObject
{
         private NameValueCollection _items;

        public AppSettingsWrapper()
        {
            _items = ConfigurationManager.AppSettings;
        }

         public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            result = _items[binder.Name];
            return result != null;
        }
}

Here, the AppSettingsWrapper class extends the DynamicObject class. In its constructor, it initializes a private NameValueCollection member with the AppSettings property of the ConfigurationManager class (which internally reads and returns the content from appSettings section of the App.config or a Web.config file of an application.
It also overrides the TryGetMember method of the DynamicObject class. This method gets called when one tries to access property from an instance of this class. The binder parameter of this method has some useful properties and one such property is Name, which gives us the name of the property being accessed. Here, we simply search the internal NameValueCollection using binder.Name as the key. We have to return a boolean indicating whether the member access was successful.

This is how it can be used in a program:

class Program
{        
         static void Main(string[] args)
        {
             //Using traditional API
           Console.WriteLine("MyKey1 accessed traditionally : {0}",
                 ConfigurationManager.AppSettings["MyKey1"]);

             //Using our wrapper
            dynamic appSettings = new AppSettingsWrapper();
           Console.WriteLine("MyKey1 from wrapper: {0}", appSettings.MyKey1);            
        }
}

Here, we demonstrate both ways to access the configuration item (using traditional API as well as our wrapper).
I’m not going to illustrate the obvious way to access the item using traditional API and just focus on the second approach here.
They key here is to note the following declaration:

dynamic appSettings = new AppSettingsWrapper();

The dynamic keyword here instructs the compiler that it should not enforce compile time type checking when any property, method or a member is accessed from the instance appSettings. This allows us to access arbitrary properties like appSettings.MyKey1 in code and the compiler won’t complain. Obviously, a runtime exception will be thrown if such a key doesn’t exist in the configuration file.
Please note that though appSettings is an instance of a class derived from DynamicObject, we still cannot declare it as

AppSettingsWrapper appSettings = new AppSettingsWrapper();

This will treat it as a statically typed object and we cannot have the desired dynamic behavior.
While this approach still doesn’t prevent us from mis-typing the key name (which won’t be reported until runtime and we don’t have intellisense either for dynamic expressions), it at least gives a much more readable and clearer syntax and saves us key strokes.
To read more about the DynamicObject class, visit this link on msdn.

C# 4.0 Dynamic programming to create a wrapper for reading appSettings section  (2197 Views)