Thursday, October 30, 2014

Custom Server Controls That Wrap Content

So when building a custom server control, most Google results will tell you to use a Template Control to handle wrapping your control around content. This results in markup that looks like this:

<uc:MyControl runat="server">
    <Content>
        <asp:TextBox runat="server"/>
    </Content>
</uc:MyControl>

This is annoying, since you have to specifically add a <content> section every time you'd use the wrapping control.

The solution is actually rather simple:

public override void RenderControl(HtmlTextWriter writer)
{
    // top of your wrapping code here

    foreach (Control i in Controls)
        i.RenderControl(writer);

    // bottom of your wrapping code here
}

This lets you wrap whatever code you need around whatever controls are nested inside your markup start/end tags.

Tuesday, October 7, 2014

Your Code: If you can't be an example, be a warning

I was just talking with a friend about some re-work he was having to do, and he was very frustrated by the "wasted time" he created as a result of the original work.

I told him to look at it from the Tomas Edison viewpoint: now you know what not to do, and that is just as important!

The next time you have to go blow away some code and rewrite it because of some error or mistake you got yourself into, take a good hard look at the existing code before you get rid of it. Try to figure out the anti-pattern that caused the problem, and remember it! Write it down, create a mnemonic for it, whatever you have to do!

Your goal is to implant some small seed of that anti-pattern in your brain, so that the next time you're coding along, that little corner of your brain will tickle and you'll realize you're building an anti-pattern, and fix it before it's a problem.

So many programmers talk about Design Patterns and Best Practices, but we don't bother to study anti-patterns and bad practices to understand them and question ourselves and our code to improve even the smallest and most common boilerplate code.

Interview question: Tell me about an anti-pattern you used, how you identified it, and how you fixed it?

Wednesday, June 11, 2014

A Developer's Greatest Shame

What is a developer's greatest shame?

Is it a GOTO statement?

Or PUBLIC STATIC FINAL STRING False = Boolean.True; ?

No, I'm quite convinced that a developer's greatest shame is an end-user seeing an exception screen.
Any kind of exception: Object Reference Not Set To An Instance Of An Object, 404: Not Found, PC LOAD LETTER.

Honestly, no client should ever see "Object Reference Not Set To An Instance Of An Object". They should see a nice message saying "the <blah> setting has not been set, please have your administrator configure this setting".

Zero code should exist outside of a try-catch block!

An end-user seeing an exception page should be the greatest shame a developer can have. Developer mind you... mere coders don't care, they're paid to make it work, not to make it work right. "Talk to me about exception handling" should be a required line in every developer interview.

"Yeah, but all those try-catch add so much extra code to your product!"

Yes, 7 lines minimum:
try
{
    //<your existing code>
}
catch (ExceptionType ex)
{
    throw ex;
}
And if I ever see an empty Catch, I want to punch someone! It would do nothing: you're catching the exception and doing nothing with it. No log, no throw, no goto, no nothing. At the least, log it internally so the dev can see what's happening when he debugs, without having to manually step through every line. Preferably, put intelligence in there so it can tell the user what happened and why it didn't do what they were expecting it to do:

  • "Cannot access the database"
  • "'asdf' is not a valid date"
  • "I cannot divide by zero"
  • "Chuck Norris exception, recovering from roundhouse kick, please wait..."

Just something useful! Even something funny... (or customizable).

Don't put one gigantic try-catch around the entire 50-line method call

Break it up so that the exceptions are useful to the developer. Try-catch an action: instantiate something, assign it a value, access a property of it. Wrap that before you move on:
object variable = null;
variable = factory.getNewObject(context,settings);
int result = variable.IntValue;
Wrap that in a try catch!!!

  • factory can throw errors
  • variable.IntValue might throw an ObjRef error

There's two right there, catch those before moving on.

It's not that hard and it makes life so much easier later on

It's really funny how much easier your life is when you just follow a few good practices. People scoff at you adding all this extra code, up until something goes horribly wrong and it takes you 20 seconds to say "oh, it's bad data in the database, clean that up, the code's fine, no need to emergency patch it".