Frameworks suck

… because they fail to do what some/most/any/one developer expects them to do.

Say you have a list of key-value-pairs you want to persist. For instance, in a file.

In the days of Microsoft.NET 2.0 this obviously is an IDictionary, and, for sake of simplicity, let’s assume it’s IDictionary<string,string>.

Save to file you could write yourself, but we are framework-aware and want full leverage. So, the framework has serialization.

BinaryFormatter has issues around typing, security and versioning and SoapFormatter is deprecated and doesn’t do generics anyway. DataContractSerialization is 3.0 but we have our good friend XmlSerializer who’s as good as it gets.

So we write

new XmlSerializer(dictionary.GetType()).Serialize(stream, dictionary)

and hit the floor of the framework. Good intention, reasonable expectations, utter failure.

Of all types in the world, XmlSerializer cannot, will not, want’s not serialize IDictionary. It is special cased to fail on IDictionary; it doesn’t support it due to "schedule constraints". Blatant ignorance of the fact Dictionary implements ISerializable.

So what do we do? We know IDictionary is a list of KeyValuePairs. Since we’re not planning on modification, KeyValuePair[] is sufficient.

No complaints? Well, KeyValuePair is not exactly XmlSerializable because it’s immutable. A good thing anywhere else, but here, it sucks.

Long story short?

 

    public struct Pair<TKey, TValue>

    {

        public TKey Key;

        public TValue Value;

 

        public Pair(KeyValuePair<TKey, TValue> pair)

        {

            Key = pair.Key;

            Value = pair.Value;

        }

 

        public static implicit operator Pair<TKey, TValue>(KeyValuePair<TKey, TValue> pair)

        {

            return new Pair<TKey, TValue>(pair);

        }

 

        public static implicit operator KeyValuePair<TKey, TValue>(Pair<TKey, TValue> pair)

        {

            return new KeyValuePair<TKey, TValue>(pair.Key, pair.Value);

        }

    }

 

    public class DictionarySerialization<TKey, TValue>

    {

        private readonly static XmlSerializer serializer = new XmlSerializer(typeof(Pair<TKey, TValue>[]));

 

        public static void Serialize(Stream stream, IDictionary<TKey, TValue> dictionary)

        {

            Pair<TKey, TValue>[] items = new Pair<TKey, TValue>[dictionary.Count];

 

            int index = 0;

            foreach (KeyValuePair<TKey, TValue> item in dictionary)

            {

                items[index++] = item;

            }

 

            serializer.Serialize(stream, items);

        }

 

        public static void DeserializeInto(Stream stream, IDictionary<TKey, TValue> dictionary)

        {

            Pair<TKey, TValue>[] items = (Pair<TKey, TValue>[])serializer.Deserialize(stream);

 

            foreach (Pair<TKey, TValue> item in items)

            {

                dictionary.Add(item);

            }

        }

    }

What have I done to deserve this?

Please note: source code fragment sample provided "AS IS", without support or warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and non-infringement. In no event shall the author or copyright holder be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the software or the use or other dealings in the software.

Advertisements
This entry was posted in Coding Horror. Bookmark the permalink.

One Response to Frameworks suck

  1. Tom says:

    I can’t tell what year this was posted, but I got a good laugh from your delivery of it. Thanks for the laugh and the code!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s