Archive

Posts Tagged ‘Configuration’

Dynamic Strongly-Typed Configuration in C#

June 29, 2007 aabs 2 comments

    I’ve written at great length in the past about the perils of configuration, and I thought I’d written as much as I was willing on the topic. But I thought it was worth describing this solution, since it was so neat, and easy, and had most of the benefits of text based configuration and strongly typed inline configuration. I was recently messing about with some WCF P2P code, and the setup code had some configuration that looked like a likely candidate for a strongly typed configuration object that wouldn’t change frequently. I think this solution neatly addresses one of the main objections to hard coded configuration, which is that we do sometimes need to change configuration data at runtime without having to take down the servers or recompile them.

    The idea behind this solution stems from the use of a plug-in architecture such as the forthcoming System.AddIn namespace to arrive in VS2008. In that you get the options to load a namespace from a designated directory and make use of types found inside of the assembly. Why not use the same approach with configuration? We can dynamically load configuration assemblies and then use a single configuration setting to specify which type from those assemblies would be used as the new configuration. This has all the benefits normally reserved for text based dynamic configuration such as System.Configuration.ConfigurationManager, but with the added benefits of strong typing, inheritance, calculated configuration settings and added performance of POCOs.

    My WCF program was a simple chat client that I hope to be able to use between members of my family. Typical configurations were MeshAddress, and CredentialType that are unlikely to ever change frequently. Each of these configuration settings was defined on an interface called IChatClientConfig. Implementing that full interface was my default configuration class called DefaultChatConfig. That provided all of my defaults, and is perfectly usable. I then specialized that class with some others, for example with a different mesh address for chatting with people at work. A class diagram for the configuration objects are shown below.

    clip_image001

    Each class just provides a new implementation for the field that it provides a different value for.

    Loading the configuration is extremely simple. First you have to say which one of those classes you want to use for your configuration.

    <appSettings>
        <add key="P2PConfigSettings" value="ChatClient.Configuration.TechChatConfig, ChatClient.Configuration, Version=1.0.0.0"/>
    </appSettings>
    

    This simple app setting is the fully qualified type name of the TechChatConfig class on the bottom right of the diagram above. Which will be a default chat configuration with whatever tech chat configuration added. That’s all the prerequisites for loading configuration. Not all I need to do to load the configuration is this:

    private static IChatClientConfig GetConfigObject()
    {
        string configType = ConfigurationManager.AppSettings["P2PConfigSettings"];
        Type t = Type.GetType(configType);
        return Activator.CreateInstance(t) as IChatClientConfig;
    }
    

    Get whatever type I specified as a string from the configuration file, get the type specified by that string create and instance and return it. Simple. That configuration could be then stored as a singleton or whatever you need to do.

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
    public partial class Window1 : IPeerChat
    {
        private IChatClientConfig configuration;
    

    In my case I just stored it in the window object I was using it for – my chat client only has one window! Now I can just use it, whenever I do any comms.

    private NetPeerTcpBinding CreateBindingForMesh()
    {
        NetPeerTcpBinding binding = new NetPeerTcpBinding();
        binding.Resolver.Mode = config.PeerResolverMode;
        binding.Security.Transport.CredentialType = config.CredentialType;
        binding.MaxReceivedMessageSize = config.MaxReceivedMessageSize;
        return binding;
    }
    

    So you see that the process is very simple. With the addition of an AddIn model we could use a file system monitor to watch the configuration file, detect changes and reload the configuration object singleton using the mechanism described above. That fulfils most of the requirements that we have for type safety, performance, dynamism, intelligence, and object orientation. Very few configuration scenarios that fall outside of the bounds of this solution should be solved using local configuration settings anyway – in those cases you really ought to be looking at an administration console and database.

Categories: Uncategorized Tags: , ,

Why type safety in configuration is a good thing

November 1, 2006 aabs Comments off

How many times have you seen a piece of code like this?

bool shouldUseXyzService = bool.Parse(WebConfiguration.AppSettings["shouldUseXyzService"]);
if(shouldUseXyzService){…}

It’s a familiar thing to most programmers. And most programmers never stop to think about just how evil it is. In my last few posts I’ve been suggesting that we ought to be using something like this:

if(SomeConfiguration.ShouldUseXyzService){…}

Why is it better?

Type Safety.

The key reason is automatic type safety. Type safety ensures that when you make a call to another component you get the data you are after in the format you wanted. Imagine if you had to check for ‘y’, ‘yes’, ‘true’, ‘1′ and so on. It wouldn’t take you long before you started making sure that you had a single representation of true. And that’s what type safety ensures in the case of a config system.

There is another form of type safety at stake. The config data might be in the wrong format. You code ought to have looked like this:

try{
   bool shouldUseXyzService = bool.Parse(WebConfiguration.AppSettings["shouldUseXyzService"] .Trim().ToLower());
   if(shouldUseXyzService){…}
}catch(FormatException e){…}

What do you do if the config is in the wrong format? Rethrow? Set a default value? Rethrowing means your app is toast. Setting a default value will yield unpredictable behavior, especially when the config files are different between production and release builds. You never have this kind of production weirdness with typed configuration objects because that sort of syntactic error never makes it through a compilation.

Performance

Unless you have a mechanism to load a cache the contents of the configuration file in memory, you are inevitably going to have to make a file access every time you access the config variable. With most built-in config systems, you will get that for free. But most config files are stored in a name value dictionary format of some sort – a hash table. Accessing a hashtable every time you want to get at a variable is very expensive compared to the kind of inlined access you would get if you were accessing a const or read-only variable on an abstract type.

A built in config system (such as the one found in .NET) is not going to know what type your data is in, so it can’t store a typed representation of the data for fast access. Instead it will store the data in a string. That means that you have to parse your data every time you access it. In the case of a bool above it might be reasonably straightforward to parse it, but your still talking about a lot of CPU cycles wasted for no advantage. Imagine if your config was a date time or currency value that had a lot of logic required to convert into local specific object representations. In those cases the simplicity of the .Parse(…) API hides a major time waster.

No test guarantees

When you run a set of tests over a piece of code – it gives you an assurance that the code works. You can deploy it to production and it will behave in the same way there. When you have a set of guiding policy variables that are not part of the test regime you are already losing some of the safety that you have with fully tested code.

Readability

I doubt that there would be any debate that the typed configuration object code above is more readable than the first or second untyped examples. The intent is clear, the format is understood by the runtime and it gets intellisense support. The typed configuration object has another level of readability. If you put a whole bunch of related configurations together in a class called XyzServiceConfigurations it is much easier for developers to know where to go to get a specific setting. I’ve seen a few systems that define a Constants class, but generally these classes are not broken up into semantically meaningful units. Why? I don’t know. We can go further by defining relationships between config objects we can dispense them in consistent ways using class factories.

Designers should really be looking for justifications for untyped config systems, not the reverse.

Categories: Uncategorized Tags: , ,