Friday 5 October 2012

Caught between declarative and programmatic custom configuration element methods

I don’t need to create custom configuration sections for .NET apps very often; whenever I do, it seems like an awkward process.

I hit a new problem recently; only a small one, but sufficiently frustrating that I need to commit it to memory. I was mixing up the two distinct methods for creating the configuration: programmatic, and declarative (or attributed).

The symptom was a  “key has already been added” exception when loading a new application’s configuration. The exception was thrown by configuration elements added to a custom ConfigurationElementCollection.

The error seemed clear: I’d already added a config item with this key. So how do I define the key for an item? Figuring it’d be easy I leant on Intellisense, found the IsKey attribute and thought – great! I can define the properties that make up the key. Happily, I added key properties to my derived ConfigurationElement, suitably attributed.

Daft.

It didn’t work, and it took me a little while to figure out what was going on. I’d forgotten that the ConfigurationElementCollection acts as a factory of sorts – and is also given the responsibility of generating the key. I’d filled out some simple placeholder code to generate an element key there which clearly wasn’t up to the task.

It was only after that, when I looked more deeply into the ConfigurationElementCollection that I realised I’d been mixing mechanisms for expressing the custom configuration. The IsKey attribute was irrelevant, as the mechanism I was using to generate the collection was programmatic.

So, multiple lessons learned: don’t lean on Intellisense without reading the docs; think about the structure of your data, even if it’s a configuration element; and don’t add placeholder code for functions like key generation.

No comments: