So I boot up my laptop and start pounding away at my Windows app, making changes that will add so much value that it's dripping from my screen (waitaminute...that's not value...EWWWW!). It should be noted that I'm the sole proprietor of this application on the basis that I'm the sole .NET developer on the team.

Hit F5 to let 'er rip and BAM! at the section that loads my custom config section from app.config, code I wrote almost by rote several weeks ago and which I've promptly forgotten because I haven't touched it since.

My custom config is pretty straightforward. Here's the app.config:

<configSections>
   
<section name="Handlers" 
      
type="CodingHillbilly.SkinningManager.Windows.Configuration.MyConfigurationHandler, CodingHillbilly.SkinningManager.Windows" />
</configSections>

<Handlers>
   
<Handler name="Raccoon" 
         
assemblyName="CodingHillbilly.Handlers.Raccoon" 
         
className="CodingHillbilly.Handlers.Raccoon.RaccoonHandler">
   
</Handler>
   <Handler name="Squirrel" 
         
assemblyName="CodingHillbilly.Handlers.Squirrel" 
         
className="CodingHillbilly.Handlers.Squirrel.SquirrelHandler">
   
</Handler>
   <Handler name="Possum" 
         
assemblyName="CodingHillbilly.Handlers.Possum" 
         
className="CodingHillbilly.Handlers.Possum.PossumHandler">
   
</Handler>
</
Handlers>

In the ConfigurationHandler, I create an object for each handler, gather them up in a Hashtable and return it:

public class MyConfigurationHandler : IConfigurationSectionHandler
{
   public object Create( object parent, object configContext, XmlNode section )
   {
      Hashtable skinninHandlers = new Hashtable( );

      foreach ( XmlNode handler in section.ChildNodes )
      {

         if ( handler.NodeType != XmlNodeType.CDATA && handler.NodeType != XmlNodeType.Whitespace )
         {
            string displayName = handler.Attributes["name"].Value;
            string assemblyName = handler.Attributes["assemblyName"].Value;
            string className = handler.Attributes["className"].Value;

            MyHandlerObject handlerConfig = new MyHandlerObject( displayName, assemblyName, className );

            skinninHandlers.Add( displayName, handlerConfig );
         }
      }

      return skinninHandlers;
   }
}

And in the main code:

handlers = (Hashtable) ConfigurationSettings.GetConfig( "Handlers" );
foreach ( MyHandlerObject handler in handlers.Values )
{
   this.comboBoxHandlers.Items.Add( handler.Name );
}

Like I said, I wrote this long ago in a different time and for whatever reason, it starts complaining this morning. Whining that it can't cast the objects in handlers.Values to a MyHandlerObject anymore. But when I debug, every object in handlers.Values is, in fact, a CodingHillbilly.SkinningManager.Configuration.MyHandlerObject object.

The key was in the type attribute of the Handlers section. Yesterday, I handed off my work in progress to someone to start testing and in a fit of user-friendliness, I didn't want the executable to be named CodingHillbilly.SkinningManager.Windows.exe, so I changed the name of the assembly in the project properties to UltimateSkinner.exe.

Hence, it was creating handlers based on the old assembly and trying to cast them to handlers from the new assembly because the Debug folder still actually contained the old CodingHillbilly.SkinningManager.Windows.exe. I suspected there was some reference issue so I cleared the Debug folder completely, re-compiled and lo! Now it can't find a reference to the assembly to even create the config handler.

From there it was a quick fix to the <section> to reference the correct assembly:

   <section name="Handlers" 
      
type="CodingHillbilly.SkinningManager.Windows.Configuration.MyConfigurationHandler, UltimateSkinner" />

So the moral of the story is: don't do anything to make the user's life easier.

moo