Published
Tuesday, June 17, 2008 6:21 AM
by
martin
I'm currently working on an app that has to run on v2.0 of the .NET platform (with no SP applied). The particular behaviour I'm talking about may have changed in more recent versions - I haven't had time to check - but I was struck by something and just had to write about it.
When you're working on a UserControl, Visual Studio sets the value of a property DesignMode to true whenever it loads your control into the visual designer. This allows you to ensure that any code that depends on runtime artifacts doesn't run in the designer. But if you search, you'll find lots of folks bemoaning the fact that DesignMode isn't set before the constructor of your control runs. Again, maybe this has changed, I should check...
That means you have a problem if code in your constructor depends on constructs that are only available at runtime. There are a number of workarounds posted on the web, but none of them struck me as very nice, and some just didn't work for me. So I did the "obvious" workaround. I took the code that couldn't run in the designer, moved it out of my constructor and into a separate function, and did a check for DesignMode there. It works fine.
Now my control has a simpler constructor. It just initialises fields with values that are always the same. All the logic that calls into other parts of the app has been moved into my new function. I feel that my control is somehow "less-coupled" to other parts of the app now that I can construct it without those things being there. It feels more correct.
What's the catch? Well, something has to call my new function. That could be the code that instantiates my control, or I could call it from my own control's Load event handler, or from some other event handler inside my control. In my case, I chose to let the calling code do it. it worked fine but I still walked away thinking I'd made my codebase more complex to workaround an "issue" in VS2005.
But today I was doing further development against my control. It struck me that the additional function I introduced has actually allowed me greater freedom in the way I initialize the control and has actually simplified my codebase in the end. The feeling of correctness I got from refactoring the constructor was borne out in my ability to reuse this control in ways I didn't anticipate.
There's a lesson in that. You might feel coerced into writing code a certain way, just to workaround a quirk in your tools or platform, but that doesn't mean the workaround is actually worse than what you originally intended. It could be better.