Some easy reading for today.

I recently completed the process of designing and implementing the configuration layer for my company’s new platform. As with everything I’m doing with the new product, a practical amount of care and consideration was devoted towards ensuring that this particular piece was being committed in a manner as correct as possible.

I’ve dealt with .NET’s configuration system more than once, but for this I decided to take a closer look at some of the MSDN documentation and existing Microsoft configuration-related code. I was surprised to learn that there are two completely separate models to follow when implementing the various custom configuration types.

This article covers these models. Not the most exotic subject in the world (indeed, a very simple subject), and one that already has some fairly excellent writings dedicated to it already; I was unable to find a clear and concise overview of the matter however.

Configuration Coding Models

The declarative coding model is the one which I would argue is the more “famous” of the two; indeed it seems to be the way it is taught to the masses, both by Microsoft and other entities. The declarative coding model involves the use of those configuration attributes we all know and love, such as ConfigurationCollectionAttribute, which would go over properties meant to return a collection of configuration elements.

The other model is referred to as the programmatic coding model. This model is notable in that it seems to be the preferred approach taken by Microsoft for what seems to be every custom configuration element defined in the .NET Framework. In fact, spotting this pattern is truly what lead me to take some time looking for additional information in the first place. Given the frequency of its occurrence in the .NET Framework, one could make the assertion that use of the programmatic coding model within Microsoft’s code is company policy.

I pay great attention to matters like this. Time and time again, with regards to various Microsoft technologies, I’ve observed instances of a dual dichotomy of recommended methodologies and techniques to aid the consumption of said technologies. There will be one set of methodologies and techniques fervently evangelized and marketed for public consumption, and then there will be a lesser spoken of set of methodologies and techniques which tend to exhibit the characteristics of being both the more “correct” way of doing things as well as happening to be the way Microsoft approaches the use of the technology internally.

An example of this phenomenon is VSTO. VSTO is the very publicly touted way to do Office extensibility when using the .NET Framework as your platform. In actuality, if your intent is to create an add-in that is more than a very minor product feature, VSTO is insufficient and a very poor way to go about it. You will increase your development time, drive up your support bills, and be unable to deliver to some key demographics due to technological limitations.

The instance of this phenomenon that we have here with the configuration system is not anywhere near as severe as some others, and barely even qualifies for the distinction; regardless of barely qualifying as an instance of this described phenomenon, I’d argue that it still does qualify.

But I digress, and I’ve already written a piece on what I just wrote above.

Model time.

Declarative Coding Model

The declarative coding model is the simpler of the two models, and will require less time in order to get something from nothing to out the door.

The rules imposed by this model are simple (if not a bit unclear at times) in that you need to decorate configuration element properties with the appropriate ConfigurationPropertyAttribute, which is also where you provide the configuration for those elements as well.

Clearly, those attributes are defined so they may be read during runtime by the Framework itself. Being attributes, Reflection is used in order to do just that. Once this information has been obtained by the framework’s configuration system, the element property objects will be created and initialized appropriately.

Here’s an example of a configuration section using the declarative approach:

    /// <summary>
    /// Provides a very useful configuration section.
    /// </summary>
    public sealed class VeryUsefulSection : ConfigurationSection
    {
        /// <summary>
        /// The schema name for the child element containing the most useful thing in existence.
        /// </summary>
        private const string MOST_USEFUL_CHILD = "mostUseful";

        /// <summary>
        /// The schema name for the child collection element containing all of the stuff in the universe
        /// deemed to be useful.
        /// </summary>
        private const string USEFUL_STUFF_CHILD = "usefulStuff";

        /// <summary>
        /// Gets or sets the configuration element containing the most useful thing in existence.
        /// </summary>
        [ConfigurationProperty(MOST_USEFUL_CHILD, IsRequired=true)]
        public UsefulElement MostUseful
        {
            get { return (UsefulElement) base[MOST_USEFUL_CHILD]; }
            set { base[MOST_USEFUL_CHILD] = value; }
        }

        /// <summary>
        /// Gets the collection of all the stuff in the universe deemed to be useful.
        /// </summary>
        [ConfigurationProperty(MOST_USEFUL_CHILD, IsRequired=true)]
        [ConfigurationCollection(typeof(UsefulElement))]
        public UsefulElements UsefulStuff
        {
            get { return (UsefulElements) base[USEFUL_STUFF_CHILD]; }
        }

        // I normally have some additional helper methods here for every section I write, but they don't
        // affect the topic at hand.
    }

As the above code makes very evident, what we have here is a configuration section that deals with really useful stuff.

Take a look at the properties of the section. Each property here corresponds to a configuration element in a file. Each one also has one or more configuration-related attributes decorating them.

Take a look at the MostUseful property. This property returns a UsefulElement type object, which would correspond to a single<usefulElement>-like XML element in a configuration file. It is being decorated with a single ConfigurationProperty attribute.

Then we have the UsefulStuff property. This returns a UsefulElements type object, which is actually an implementation of theConfigurationElementCollection type, responsible for returning multiple UsefulElement type objects. Not only does this property have a ConfigurationProperty element, but a ConfigurationCollection attribute as well.

All of the various attributes shown above and how they are used fall in line with the declarative coding model. At runtime, these configuration elements will be reflected through, information will be discovered, and then the necessary objects will be created.

Programmatic Coding Model

Now, onto the other model available for us to use: the programmatic coding model, or as I like to call it, the way Microsoft does it.

Why is there even another model? Isn’t the model we just went over a shining example of the pinnacle of human ingenuity in regards to configuration-related structure creation? Oh it could very well have been just that, if not for a few issues.

  1. Using the declarative model infers that the primary method of information discovery used will be reflection. So there is a performance cost with that, you decide how important that is to you.
  2. And then, on another performance-related note: the result of the process that creates the actual configuration elements is not cached, at least not fully. This means that there will be some type of cost incurred each time you need to load a configuration-related element.
  3. Sometimes attributes can be a real pain in the ass! Though, I do normally love attributes; for some reason their use in conjunction with the .NET configuration system fouls my mood.

Implementing a configuration element type using the programmatic coding model is actually a very simple affair. All we need to do is override the type’s Properties property, which returns a ConfigurationPropertyCollection object.

Let’s a take a look at the code for the same section as the one defined in the previous section, but one that is based on the programmatic coding model instead:

    /// <summary>
    /// Provides a very useful configuration section.
    /// </summary>
    public sealed class VeryUsefulSection : ConfigurationSection
    {
        /// <summary>
        /// The schema name for the child element containing the most useful thing in existence.
        /// </summary>
        private const string MOST_USEFUL_CHILD = "mostUseful";

        /// <summary>
        /// The schema name for the child collection element containing all of the stuff in the universe
        /// deemed to be useful.
        /// </summary>
        private const string USEFUL_STUFF_CHILD = "usefulStuff";

        private static readonly Lazy<ConfigurationPropertyCollection> _Properties
            = new Lazy<ConfigurationPropertyCollection>(InitializeProperties,
                                                        LazyThreadSafetyMode.PublicationOnly);

        /// <summary>
        /// Gets or sets the configuration element containing the most useful thing in existence.
        /// </summary>
        public UsefulElement MostUseful
        {
            get { return (UsefulElement)base[MOST_USEFUL_CHILD]; }
            set { base[MOST_USEFUL_CHILD] = value; }
        }

        /// <summary>
        /// Gets the collection of all the stuff in the universe deemed to be useful.
        /// </summary>
        public UsefulElements UsefulStuff
        {
            get { return (UsefulElements)base[USEFUL_STUFF_CHILD]; }
        }

        /// <inheritdoc/>
        protected override ConfigurationPropertyCollection Properties
        {
            get { return _Properties.Value; }
        }

        /// <summary>
        /// Creates a <see cref="ConfigurationPropertyCollection"/> object containing all configuration
        /// properties belonging to this element.
        /// </summary>
        private static ConfigurationPropertyCollection InitializeProperties()
        {
            return
                new ConfigurationPropertyCollection
                    {
                        new ConfigurationProperty(MOST_USEFUL_CHILD,
                                                  typeof (UsefulElement),
                                                  null,
                                                  ConfigurationPropertyOptions.IsRequired),
                        new ConfigurationProperty(USEFUL_STUFF_CHILD,
                                                  typeof (UsefulElements),
                                                  null,
                                                  ConfigurationPropertyOptions.IsRequired)
                    };
        }
    }

There it is. As you can see, we no longer have to deal with attributes, although we still have to ultimately provide the element-related configuration in the InitializeProperties initializer method. We now provide a static field named _Properties which will maintain a static reference to our element information. The value behind this is ultimately returned in the Properties override, which is also new from the old code.

Details, Details!

Why do we have the value for the configuration properties stored in a static field? Because I only want to have to initialize the data once per type per application domain lifecycle. Whether it saves a minute or a billionth of a nanosecond, it doesn’t matter, because it’s simply logical that you would only initialize something whose parameters are defined at compile-time once.

A better question is: Why do I have the configuration properties wrapped with Lazy<T>? That’s a good question. Let’s go over some points related to that.

  • Because we’re playing with static fire here, we of course need to make sure we aren’t shooting ourselves in the face in regards to threading issues.
  • Static field initializers are guaranteed to be thread-safe, as they’re only executed one per application domain lifecycle.

OK. Wait a second, it sounds like that a justification was just made to use a simpler static field initialization of theConfigurationPropertyCollection as opposed to delaying the initialization by wrapping it with a Lazy<T>.

Indeed, you might be 100% fine if you just stick to a static field initializer. The example code I’ve provided is influenced a bit by the platform I’ve been working on that my company’s products will be based on. So, I have a few requirements that led me to choose to use a Lazy<T> type.

And by the way, the reason why I’m even going over these reasons is because, while the use of Lazy<T> just by itself by a developer would frankly (and unfortunately) be impressive to myself, using it to be lazy for the sake of being lazy (in other words: you have no reason) would do well to cause me to question the competency of the developer. It’s also an interesting discussion.

The reason I’m lazily initializing the property collection is because it is possible that an application based off of the platform these configuration classes might run without ever actually needing to use them. Why spend time performing work if you don’t need to perform that work? When the solution to that is as simple as wrapping a type with a Lazy<T>, why not? The solution can be provided unconsciously even.

But hold on…if an application never uses these configuration files, then wouldn’t the static field initializers never go off? If you’re vaguely familiar with static initialization and the C#/CLR specs, you might think that to be case.

However, that’s not necessarily the case. In fact, with .NET 4.0, static field initialization now occurs at an “implementation-dependent” time. In other words, static field initialization, while appearing to be based on a lazy strategy itself, gives absolutely no guarantees or actual guidance as to when it might occur.

But wait! Why don’t we just move the static fields into a static constructor? Yes, if we define an explicit static constructor, we suddenly have deterministic time of initialization. Indeed, the spec states that a static constructor will be triggered if one of the following events occur:

  • An instance of the class type is created.
  • Any of the static members of the class type are referenced.

Ah, so going with the first point there, know that by avoiding all use of instances of these configuration types we avoid the initialization routine from firing due to the first condition defined above.

But the second condition is what kills the approach of using a static constructor. In the actual platform code, there are some static properties on these types that may be referred to without ever reading the configuration itself. These properties were not included, and they’ll not be discussed as they are both outside the topic and proprietary (and plus, I don’t feel like it!)

Now, how long did it take me to reason the above and use a Lazy<T> to hold the properties while I was actually writing my platform code? Probably 10 seconds max. Articulating this reason in writing certainly added some time onto that, however.

The point I’m making here is that if spending more than 10 seconds on a decision like the one just made could be considered a waste of time.

Matt Weber

I'm the founder of Bad Echo LLC, which offers consulting services to clients who need an expert in C#, WPF, Outlook, and other advanced .NET related areas. I enjoy well-designed code, independent thought, and the application of rationality in general. You can reach me at matt@badecho.com.

 Leave a Reply

(required)

(required)

You may use these HTML tags and attributes: <a href="" title="" rel=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

 
   
© 2012-2013 Matt Weber. All Rights Reserved. Terms of Use.