ConfigurationSection Lesson on ConfigurationErrorsException

I was playing around with some old code in which I had a custom ConfigurationSection (see code below). I had an attribute in the configuration section that I wanted to change from an Int32 to a Double. Seems a simple change. Just a little refactoring of the ConfigurationElement class changing the "int" declaration to "double" and it compiles. But kablam! It does not run but throws a nasty System.Configuration.ConfigurationErrorsException with this explanation:

The default value for the property 'size' has different type than the one of the property itself.

Huh? Turns out the type inference on the DefaultValue property in the ConfigurationProperty attribute is rather picky. Here's what I had originally:

[ConfigurationProperty("size", DefaultValue = 1, IsKey = false, IsRequired = true)]
public int Size
{
    get
    { return (int)this["size"]; }
    set
    { this["size"] = value.ToString(); }
}

And here's what I changed it to thinking it would run just fine:

[ConfigurationProperty("size", DefaultValue = 1, IsKey = false, IsRequired = true)]
public double Size
{
    get
    { return (double)this["size"]; }
    set
    { this["size"] = value.ToString(); }
}

Just because the above code compiled, does not mean it will work correctly. So here's what really worked:

[ConfigurationProperty("size", DefaultValue = 1.0, IsKey = false, IsRequired = true)]
public double Size
{
    get
    { return (double)this["size"]; }
    set
    { this["size"] = value.ToString(); }
}

Small but important lesson to learn. Here's the whole code and following it the snippet from the config file in case this is the first time you've written a custom config handler.

using System;
using System.Collections;
using System.Text;
using System.Configuration;
using System.Xml;

namespace MyConfigBox
{
    public class SizeLimitConfigurationSection : ConfigurationSection
    {
        [ConfigurationProperty("hostSize")]
        public HostSizeConfigCollection HostSize
        {
            get
            {
                return ((HostSizeConfigCollection)(base["hostSize"]));
            }
        }
    }

    [ConfigurationCollectionAttribute(typeof(HostSizeConfigElement))]
    public class HostSizeConfigCollection : ConfigurationElementCollection
    {
        protected override ConfigurationElement CreateNewElement()
        {
            return new HostSizeConfigElement();
        }

        protected override object GetElementKey(ConfigurationElement element)
        {
            return ((HostSizeConfigElement)(element)).Name;
        }

        public void Add(HostSizeConfigElement element)
        {
            this.BaseAdd(element);
        }

        public void Remove(string key)
        {
            this.BaseRemove(key);
        }

        public void Clear()
        {
            this.BaseClear();
        }

        public HostSizeConfigElement this[int idx]
        {
            get { return (HostSizeConfigElement)this[idx]; }
        }
    }

    public class HostSizeConfigElement : ConfigurationElement
    {
        public HostSizeConfigElement() { }
        public HostSizeConfigElement(string name, double size)
        {
            this.Name = name;
            this.Size = size;
        }

        [ConfigurationProperty("name", DefaultValue = "_", IsKey=true, IsRequired = true)]
        [StringValidator(InvalidCharacters = "~!@#$%^&()[]{}/;'\"|\\", MinLength = 1, MaxLength = 260)]
        public string Name
        {
            get
            { return (string)this["name"]; }
            set
            { this["name"] = value; }
        }

        [ConfigurationProperty("size", DefaultValue = 1.0, IsKey = false, IsRequired = true)]
        public double Size
        {
            get
            { return (double)this["size"]; }
            set
            { this["size"] = value.ToString(); }
        }
    }
}

And now here's the config file (some items removed to clean it up a bit and just show the relevant parts):

<?xml version="1.0"?>
<configuration>
    <configSections>
        <section name="sizeLimits" type="MyConfigBox.SizeLimitConfigurationSection, MyConfigBox" />
    </configSections>
    <appSettings/>
    <connectionStrings/>

    <sizeLimits>
        <hostSize>
            <add name="netbrick.net" size="17.5" />
            <add name="duovia.com" size="42.4" />
        </hostSize>
    </sizeLimits>

</configuration>

And here's an example of how to use the custom config handler in code:

SizeLimitConfigurationSection config =
   (SizeLimitConfigurationSection)(System.Configuration.ConfigurationManager.GetSection("sizeLimits"));
//now use config to get at the items in the hostSize collection of HostSizeConfigElement objects

So watch those attribute values because sometimes the compiler won't.

Heap, Stack, Reference Types and Value Types in .NET

When something works well on its own with a high level of reliability, we tend to take it for granted and forget about the mechanics of how it works. We turn the key of our car and expect the engine to fire up. No thought is given to the inner workings of the internal combustion engine.

We write .NET code and expect the CLR and its garbage collector to manage memory for us without having to think much about value types, reference types, the stack and the heap. We just write code that works and thank our lucky stars that we've seen the last of malloc. Sure we have to dispose of some objects that reference system or outside resources manually but that's simple work.

But sometimes it's fun to look under the hood. And who knows, it might show up on a test.

So what is the heap and the stack and what is the difference between a reference type and a value type and what do they have to do with the stack and the heap and garbage collection?

You're right. I'm about to tell you. Now I'm not a compiler or CLR guru and this is not a graduate level CS class. This is a blog post, so we'll try to keep it real. There are far greater explainations that go into much more detail out there on the web and in texts. I hope this post will serve as a summary reminder of these concepts and help us understand the engine under the hood a bit better. And remember, this post is based on what I know, so if I'm wrong about something here, please feel free to correct me.

What is the Stack?
The Stack is essentially a LIFO (last in, first out) execution stream for a given thread (each thread gets its own Stack) with the most recently called method on the top containing parameters, stack allocated value types (more on that later), and references or pointers to data items in the Heap. The CLR using the JIT compiler manages what goes on the Stack. When a method returns or fires an unhandled exception, that top item on the Stack is removed and control is returned to the next item on the Stack. Sometimes you will see the Stack referred to as the "call stack."

What is the Heap?
The Heap's purpose is to hold information. The Heap is like a filing cabinet where data is stored. While the Stack is only accessed by the CLR in a LIFO fashion, the Heap can be accessed without constraint. The Heap contains the data you generally think of as variables or objects that are reference types. When we're done with things in the Heap, they have to be cleaned up to make room for other things. That's the job of the garbage collector.

What is a Value Type?
A value type is an object that is derived implicitly from the System.ValueType which overrides the System.Object virtual methods more appropriate to value types. Value types fall into to main categories:

Structs
Structs fall into these categories:
  • numeric types
    - integral types (byte, char, short, int, long, sbyte, ushort, uint, ulong)
    - floating-point types (double, float)
    - decimal
  • boolean
  • user defined structs
 
 Enumerations
 Enumerations are a set of named constants with an underlying type which can be any integral type except System.Char.

Value types are allocated on the Stack or allocated inline in a structure. This means that value types are almost always stored in the execution or call stack memory. When they're used like an object, they're wrapped up to look like a reference type and placed on the Heap. This is called boxing. Bringing the object back into use on the Stack as a value type is called unboxing.

The most important thing to remember about value types is that the assignment of one value type to another results in the data being copied. For example:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace StackHeap
{
    class Program
    {
        static void Main(string[] args)
        {
            MyData me = new MyData();
            me.Age = 42;
            me.Name = "Sam";
            me.Relationship = "married";

            MyData her = me;
            her.Age = 44;
            her.Name = "Mary";

            Console.WriteLine("I am {0} years old. My name is {1}.", me.Age, me.Name);
            Console.WriteLine("She is {0} years old. Her name is {1}.", her.Age, her.Name);
            Console.WriteLine("I am {0} to her. She is {1} to me.", me.Relationship, her.Relationship);

            Console.ReadLine();
        }
    }

    public struct MyData
    {
        public int Age;
        public string Name;
        public string Relationship;
    }
}

Output
 I am 42 years old. My name is Sam.
 She is 44 years old. Her name is Mary.
 I am married to her. She is married to me.

The assignment of the Age value applies only to the copy of the original. It is a value type.

Now consider the output if we make MyData a reference type by changing it to a class.

    public class MyData
    {
        public int Age;
        public string Name;
        public string Relationship;
    }

Output
 I am 44 years old. My name is Mary.
 She is 44 years old. Her name is Mary.
 I am married to her. She is married to me.

The assignment of the Age and Name values apply to both objects now because the variable refers to or points to the object created with the "new MyData()" call.

The same behavior can be observed in using value types and reference types as parameters. Consider this:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace StackHeap
{
    class Program
    {
        static void Main(string[] args)
        {
            MyData me = new MyData();
            me.Age = 42;
            me.Name = "Sam";
            me.Relationship = "married";

            MyData her = me;
            her.Age = 44;
            her.Name = "Mary";

            ModifySomeData(me, ref her);

            Console.WriteLine("I am {0} years old. My name is {1}.", me.Age, me.Name);
            Console.WriteLine("She is {0} years old. Her name is {1}.", her.Age, her.Name);
            Console.WriteLine("I am {0} to her. She is {1} to me.", me.Relationship, her.Relationship);

            Console.ReadLine();
        }

        private static void ModifySomeData(MyData me, ref MyData her)
        {
            me.Age = 50;
            her.Age = 50;
            Console.WriteLine("\nMy age changed to {0} as value type parameter.", me.Age);
            Console.WriteLine("Her age changed to {0} as value type parameter passed by ref.\n", me.Age);
        }
    }

    public struct MyData
    {
        public int Age;
        public string Name;
        public string Relationship;
    }
}

Output
 My age changed to 50 as value type parameter.
 Her age changed to 50 as value type parameter passed by ref.
 
 I am 42 years old. My name is Sam.
 She is 50 years old. Her name is Mary.
 I am married to her. She is married to me.

Notice that her.Age changed permanently and me.Age changed only in the "copy" in the ModifySomeData method because it was not passed as a "by ref" parameter. Now what happens to the output if we change the MyData to a class rather than a struct? Here's the output if we make MyData a reference type by making it a class:

    public class MyData
    {
        public int Age;
        public string Name;
        public string Relationship;
    }

Output
 My age changed to 50 as value type parameter.
 Her age changed to 50 as value type parameter passed by ref.
 
 I am 50 years old. My name is Mary.
 She is 50 years old. Her name is Mary.
 I am married to her. She is married to me.
 

So what happened when we passed a value type "by ref" in the example above? It was boxed into a reference type. And when we changed MyData into a class, the parameters are passed "by ref" regardless of whether the "ref" keyword is used. This is an important distinction to learn when dealing with parameter values.


What is a Reference Type?
Reference types can be a class, interface or delegate. All classes are ultimately derived from System.Object. Interfaces and delegates are special reference types. Exactly what they are and how they are used is a subject for another day. There are two built in reference types: object and string. These types are "native" to the CLR and do not require a "class definition" in code. All other reference types are defined in existing framework assemblies, third party assemblies or in your own code.

When you create an instance of a reference type or pass that instance as a parameter, a pointer is placed in the call Stack that references the object in the Heap. While value types live in the call Stack and are cleaned up with the removal of their associated execution call, the data on the Heap must be cleaned up by the garbage collector (GC).

What is the GC?
The garbage collector in the .NET CLR is the intelligent mechanism that deals with data on the Heap for which there is no reference or rather no existing pointer in the call Stack. It scans the Stack from time to time to determine if an object in the Heap is referenced. If the object is no longer referenced, it removes the object from the Heap returning that memory space to the runtime and eventually to the system.

The GC uses a "generations" approach to improve the speed with which garbage collection is done. The reason this is required is that while garbage collection is done (the traversing of the call Stack and iteration through the Heap), nothing else can be done. In other words, all processing threads are halted while garbage collection is performed.

The GC marks each object in the Heap with a generation value: 0, 1 or 2. The reason for this is that objects that make it through two garbage collection passes are likely to be objects that will live a long time, such as a Windows.Form object. On the other hand, short lived objects such as a local string literal will generally not survive one garbage collection pass. By marking objects with a generation value, the GC can prioritize its work. For example, if sufficient memory is recovered by examining objects with the generation value of zero, then further garbage collection is not required and processing may continue. This way you get a good balance between memory use and performance.

Summary
That's about all I have to say on this subject for now. I'm sure that virtual forests have been consumed in addressing these topics, but writing this up has been a good exercise for me. If you find mistakes, please let me know but go easy on me. :)

Seven Days Past the Layoff

A week after being laid off finds me wondering why I've neglected this blog. I'm currently experiencing the self recriminatory state one goes into at the end of the dead end street having recently passed the Dead End sign. Brake, execute the multi-point 180 and head back to find the turn you missed. And then realizing that the turn you missed should have been as obvious as the nose on your face.

My conscience tells me not to be too hard on myself. In one week I've had an interview or two. Have another scheduled for tomorrow. And one or two inquiries from other potential employers. Met with more than one recruiter and talked with several more. Polished the resume a bit more and started working the neglected network of friends and former coworkers--neglect as a result of me working from my home office with little real world interaction. Note to self: get out more and talk with humans face to face.

I've even taken more than one meeting from possible business partners with ideas that may or may not pan out, but I'm not taking anything off the table until I replace my mainstream income.

So if anyone needs a C# dev guy with some architecture leanings, grab my resume and give me a shout.

TylerJensen2008web.doc (47.5 KB)

Url Utils Helper Class May Be Helpful

Sometimes the odd helper class is useful. This one might even be a decent candidate for some .NET 3.5 extension methods. These URL utilities are quite self explanatory and by no means are a complete set of URL helper methods that would be useful, but who knows, they might have something you're looking for.

using System;
using System.Collections.Generic;
using System.Text;

namespace HelperCode
{
    internal static class UrlUtils
    {
        internal static string GetTldFromUrl(string url)
        {
            string tld = UrlUtils.GetHostFromUrl(url);
            if (tld != null && tld.Contains('.'))
            {
                string[] parts = tld.Split('.');
                if (parts.Length > 0)
                {
                    tld = parts[parts.Length - 1];
                }
            }
            return tld;
        }

        internal static string GetHostFromUrl(string url)
        {
            string retval = null;
            try
            {
                Uri uri = new Uri(url);
                retval = uri.Host.ToLower();
            }
            catch
            {
                retval = null;
            }
            return retval;
        }

        internal static string GetSchemeFromUrl(string url)
        {
            string retval = null;
            try
            {
                Uri uri = new Uri(url);
                retval = uri.Scheme.ToLower();
            }
            catch
            {
                retval = null;
            }
            return retval;
        }
    }
}

If you have a better way to do it, please, by all means, let us know. There are no doubt better ways. :)

Complexity is the Enemy of Success

Whether it be in code or business deals, complexity kills. If you're an architect and you love the elegance of endless inheritance where everything is a descendant of MyCoolRootObject or an venture capitalist trying to tie off every risk with carefully structured language that leaves a founder in the lurch and you in the driver's seat of the getaway car, you are the enemy of success. If you flout the team's style guild and name your class members with freaky names and patterns only you can recognize, you are an enemy of success. If you're a framework developer and you believe you have to add every possible toy feature in the universe to your framework, you are an enemy of success.

And enemies of success lose! Lovers of complexity may win a battle here or there, but the ash heap of history is full of them. Consider any number of technologies that have become so overbloated and difficult to work with that developers and architects look for simpler solutions. Examine the many thousands of failed startups killed by pencil pushing pinheads with no other agenda than to make the deal difficult in hopes of making it perfect, only to kill the deal with a stulted obsession with detail and gaining the advantage in every paragraph.

Simplicity is the key to success.

SqlParameter Factory

Often in my line of work, I need to create parameterized queries in code. All those overloaded constructors. Yuck. So, like a lazy guy would, I built a factory. I use it everywhere. In my personal projects and even at work when no one is looking. Here it is:

static SqlParameter CreateParameter(string name, SqlDbType type,
    ParameterDirection direction, int? size, byte? precision, object value)
{
    SqlParameter param = new SqlParameter(name, type);
    param.Direction = direction;
    if (size.HasValue) param.Size = size.Value;
    if (precision.HasValue) param.Precision = precision.Value;
    if (value != null) param.Value = value; else param.Value = DBNull.Value;
    return param;
}

And then when I'm building a command, I just do this:

cmd.Parameters.Add(DataAccess.CreateParameter("@RETURN_VALUE",
    SqlDbType.Int, ParameterDirection.ReturnValue, null, null, null));
cmd.Parameters.Add(DataAccess.CreateParameter("@ID",
    SqlDbType.Int, ParameterDirection.Input, null, null, id));
cmd.Parameters.Add(DataAccess.CreateParameter("@NAME",
    SqlDbType.VarChar, ParameterDirection.Input, 50, null, name));

Of course, it won't work for everything, but it makes quick work out of most of my parameter creation. Hooray for the factory.

Process Magic Booch Style

I recently picked up Booch, Jacobsen and Rumbaugh's new book Object Oriented Analysis and Design with Applications. It's like the textbook I never had in the OO classes I never took. (Yeah, I'm just another self taught bozo who knows the difference between a five minute class exercise and a multiple month enterprise development project.)

Among others, I have especially enjoyed Chapter 6 called simply Process. Let me quote the opening paragraph and you'll know why.

"The amateur software engineer is always in search of magic, some sensational method or tool whose application promises to render software development trivial. It is the mark of the professional software engineer to know that no such panacea exists. Amateurs often want to follow cook-book steps; professionals know that such approches to development usually lead to inept design products, born of a progression of lies, and behind which developers can shield themselves from accepting responsibility for earlier misguided decisions." pg.247

There's more and the book is a treasure trove of wisdom, but when I read this paragraph, it was nice to feel as if I had met the estimeed Booch, Jacobsen and Rumbaugh definition of professional software engineer.

I do remember looking for magic bullets when I first started teaching myself how to do software development. Fortunately through long trial and error and even greater opportunities to learn from true professionals, I gave up on looking for magic solutions long ago. Since then my life has been easier and busier and much more rewarding with regard to software development.

To their credit, the authors in Chapter 6 review the strengths and weaknesses of both agile and more traditional plan driven (sometimes called waterfall) process approaches. They begin their thesis in this chapter in addressing the traits of a successful project. Now having this is true magic. Here they are:

  • "Existence of a strong architectural vision."
  • "Application of a well managed iterative and incremental development lifecycle."

The killer qualifiers in those two statements are: "strong" and "well managed." Yikes! These are qualifications that are difficult to come by. When you do, grab them up and hold on to them for dear life. I think most of us can agree that "weak" and "poorly managed" will result in disaster every time.

Requirements in Text or Why I Hate Microsoft Word and Excel

In an ever more agile development world, we gradually learn to accept that requirements change constantly. Of course, it has always been thus, but I do remember a time when we pretended that requirements were locked and could not be changed. But then I remember delivering a product some months later which did not then meet the client's requirements despite what they had agreed to only months before. Their requirements changed, you see.

Now I work in an environment where this norm is the norm. Requirements change and they change often. Or better put, requirements are discovered daily and old requirements change into new requirements nearly as often. This is the unavoidable nature of the business I'm in. I accept it.

What I hate and cannot accept in this ever changing world are requirements documents written in a proprietary binary format. Sure they're stored in source control, so when I do a little update on my Subversion client in the morning and see that several requirements documents have changed, I'd like to just do a nice simple DIFF on them and see what's changed. But no. Oh, sure there are probably some diff tools out there I could get, but why should I when we could have just written the requirements in text or even a simple transformable XML rather than the binary gobbledygook in a Word or Excel file.

And can anyone tell me how to "blame" a change in a particular line in a Word doc on a certain author? Oh sure, I could use the gooey sticky messy change tracking--no thanks. Just give me a good text file and an editor that can handle it well.

Is my rant a cry for a product or what? Is there an existing product you can recommend? If so, please tell me. And then maybe we can ban the use of Word and Excel for the production and maintenance of requirements. We can say goodbye to the lack of transparency and traceability. We can say hello to simplicity and accountability. Ah, how would it be.