On this page.... RSS 2.0 | Atom 1.0 | CDF
# Thursday, 27 April 2006

I decided to try something new in ASP.NET 2.0 based on our needs on a current project.  To do this, I followed the tip that K. Scott Allen shares in his blog.  The difference in my case is that I thought I'd do this and make the user control in the App_Code be the base control for a handful of others.  The point here is to achieve visual polymorphism.  Put another way, I want to load up the control differently based on the sub classes rather than, say, having a big switch statement.  This is just good OOD.

The problem is that if you just set a user control in the App_Code directory as a base for other user controls, you will most likely see the following exception.  I was able to consistently reproduce it.  When ASP.NET constructs your derived user control, .NET, as usual, calls the base constructors as well.  When the base constructor is called like this (for reasons beyond my ken), I see this error:

 System.Web.HttpException: An error occurred while try to load the string resources (FindResource failed with error -2147023083).

Looking at what is actually happening (in the call stack), the error appears to be in a call that the parsed constructor makes to System.Web.StringResourceManager.ReadSafeStringResource(Type t).  If you Google like I did, you probably won't find any help (except this blog now, of course).  So on a hunch, I called the LoadControl overload like Scott Allen suggests in his piece, and it loaded fine.  On a further hunch, I then tried to use the derived control again, and voila, it worked fine.

So, since I don't have time to open a case with Microsoft, I just created that as a work around.  I have the application call LoadControl once on the base control so that ASP.NET will properly set it up for use, and then I can use it as a base.  You could do this (presumably) in Global.asax, but I just put this in the page that uses the control(s) in question.

static bool _baseUCLoaded = false;

protected override void OnInit(EventArgs e)
{
  base.OnInit(e);
  if (!_baseUCLoaded)
  {
    ASP.MyUserControlBase thing = (ASP.MyUserControlBase)this.LoadControl(
      typeof(ASP.MyUserControlBase), null);
    _baseUCLoaded = true;
  }
}

And it appears to work.  Maybe someone will enlighten me on this, but I have a hunch that it is just an unexpected scenario (a hack) that wasn't covered by testing.  In any case, it's pretty neat that it works.

Thursday, 27 April 2006 10:41:34 (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [0]  | 

Mrs. dotNetTemplar and I have decided to homeschool our children, and it is always interesting to see the various reactions you get.  Some folks think it's grand and say they wish they could.  Probably the majority just kind of stare at you blankly like you were just speaking in tonuges or kind of pat you on the head knowingly.  But the stock question, the one that you get more than any other, is "what about socialization?"

I'm not sure why or how this became common wisdom about homeschooling.  As far as I know, there haven't been any studies conducted to show that homeschoolers are socially stunted or inept.  Rather, there has been signficant research that indicates quite the opposite.  All you need to do is Google it to see more realistic information about the topic; I thought this article summed it up nicely.  Excepting those who have a vested interested in public (or private) schooling, the consensus among those informed is that homeschooling can actually be better than the alternative for socialization.

Here's a nice little snippet that I ran across today in a newsletter, The Liberator Online, I occasionally read (no, I'm not a libertarian).  The source they got it from is the New Oxford Review, which was quoting the Kolbe Little Home Journal, Fall 2005. 

When my wife and I mention we are strongly considering homeschooling our children, we are without fail asked, 'But what about socialization?' Fortunately, we found a way our kids can receive the same socialization that government schools provide.

On Mondays and Wednesdays, I will personally corner my son in the bathroom, give him a wedgie and take his lunch money. On Tuesdays and Thursdays, my wife will make sure to tease our children for not being in the 'in' crowd, taking special care to poke fun at any physical abnormalities. Fridays will be 'Fad and Peer Pressure Day.' We will all compete to see who has the coolest toys, the most expensive clothes, and the loudest, fastest, and most dangerous car.

Every day, my wife and I will adhere to a routine of cursing and swearing in the hall and mentioning our weekend exploits with alcohol and immorality.

...And we have asked (our kids) to report us to the authorities in the event we mention faith, religion, or try to bring up morals and values.

It's funny (and sad) because it is true.  The socialization one gets in public (or private for that matter) schooling is just not natural.  Where else in life are we surrounded by only peers of our own age?  In pretty much every other social environment I've been in outside of school, my peers are made up of people older and younger than me.  The grouping of kids by age, while expedient for group education, is certainly not the ideal model for socialization. 

It seems that homeschooling actually bears out to provide better-adjusted children who turn into better-adjusted adults.  When you add that to the many other benefits of homeschooling, one wonders why more people don't do it.  Well, actually, one doesn't.  It isn't the easiest path; in fact, compared to just dropping your kids off at school every day, it's significantly harder. 

Naturally, I realize that not everyone can for very good reasons (and not just, say, because it is hard).  Thankfully, my family is blessed to be in a position to homeschool, so that's what we're going to do.  I know it's not going to be a bed of roses, but at least we don't have to worry about the kids being socialized and well-adjusted; that's just a red herring that has somehow become common wisdom.

Thursday, 27 April 2006 07:55:57 (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [4]  | 
# Wednesday, 26 April 2006

Part of the common "wisdom" these days seems to be that religion and religious feeling are a bad thing.  Don't believe me?  When was the last time you heard someone say "I'm not religious about it"?  I'll wager that not much time has passed since you last heard a statement to that effect.  The speaker intends to say that he is not irrationally attached to the idea, equating, implicitly, irrationality and negativity with religious sentiment.  

I trust I need not rehash the bad rap that religion, particularly "organized religion," gets these days.  You can see it all over the media, in film, magazines, television, etc.  If an established religion is involved, particularly a Christian one such as Catholicism, the "organized" aspect of it is villified.  Religion is a byword in our society today.  Any attempt at its intrusion in public life is met with suspicion (at best) and often outright hostility.

And who are these who demonize religion?  Certainly there are the active atheists, but more often than not, it is your neighbor, or maybe even you.  After all, everybody knows that if you get "religious" about something, it is not going to end well, right?  I mean, everybody knows that lots of people have been killed and tortured for religious reasons, no?  Religion is a disease of the brain that prevents humans from thinking rationally, or so seems to be the presupposition these days.

So how about we just take a few seconds to think about history and religion?  Hmm.. we have the Crusades, the Inquisition, the 30-Years War (and other bloodiness surrounding the Reformation), and.. and.. hmmm.. Dang, I've flat run out of stock examples of how religion is so terrible.  Sure, there are the odd one-offs here and there you hear about, but this is pretty much the stuff of it that so permeates our consciousness today.  Strangely (or not so strangely), these are the same stock arguments that have been bandied about since the so-called Enlightenment.  Let's take a closer look.

The Crusades.  What can we say about them?  A lot, actually.  A lot more than the squishy tale of romance and vacuous "spiritual" comraderie displayed in the "Kingdom of Heaven."  In fact, I recommend a good and, more importantly, short book on them by the accomplished historian Thomas Madden.  In fact, you can read a short summary article treating the same topic here.  Read it, you might be surprised.

The Inquisition.  The mere word strikes disgust and fear into your heart, right?  Well, before you go swallowing mythology hook, line, and sinker, you should check out this article by Thomas Madden and, if you have more time, maybe take a gander at this book, Characters of the Inquisition, by William Thomas Walsh.  Brief summary: The Inquisition was a good thing for its time.  You don't even have to be Catholic to think so, if you'll just look into the facts and how it was a civilizing and taming influence in otherwise extremely brutal times.

The Reformation and ensuing atrocities such as the 30-Years War.  Now for these, I'd actually grant that there's a lot of bad stuff being perpetrated in the name of religion.  But the key phrase is "in the name of religion."  I won't argue against a lot of really, really bad things being done in the name of religion, but, uh, that don't make religion bad, it makes it abused.  I'd actually argue that the reason religion has gotten such a bad rap in all that is a direct result of the destabilizing and modernizing effect that the so-called Reformation had on Western society.  I'd further suggest that the only reason such atrocities have taken place in the name of religion in the four to five hundred years leading up to the 20th century is precisely because Western man was unlearning religion, particularly Catholic, Christian religion. 

The Reformation gave a carte blanche to European powers and principalities to do whatever they darn well pleased, without having to worry about the checks and balance of religious corrective exercised through the Catholic Church (as in, e.g., the Inquisition, interdicts, excommunications, etc.).  The more freed from any answer to a "higher power" that the rulers became, the more brutal and bloody things became.  This is not to say that bad things were not done by Catholic rulers as well during (and before) this time, but, like the Crusades, these were first and foremost defensive postures, reacting (and overreacting) to the new threat that Protestantized monarchs posed.  And of course, Catholics were fighting amongst themselves long before this for reasons having nothing to do with religion (they shared the same one, after all); this isn't to claim that churching culture makes men perfect but rather that unchurching culture makes them far worse or at least far more susceptible to being bad.

But if you think all the mess of the Reformation is bad, consider the absolute bloodiness of the French Revolution.  Under the guise of folks like Robespierre (whom I had the "opportunity" to do a paper on in school), these "supremely rational" people unleashed an unholy terror on their own countrymen, bathing the country in blood in the name of reason.  Yes, that's right; the French Reformation was all about "enlightenment" and "reason."  And lets not stop there.  Who was the French emperor of the late 18th and early 19th centuries that stomped all over the European continent?  Was it a religious fanatic that spilled the blood of countless thousands in the name of Enlightenment goals like public education?  No, it was a self-appointed dictator of the Enlightened world, Napoleon Bonaparte.

Did it stop there?  No, as world leaders became more and more distant and divorced from Christian rule, things progressively got worse.  Witness the many continuing continental wars of the 19th century with nothing more than national and empirical ambition as its goal.  Witness the explosion of the British Empire that ruthlessly subjugated more peoples across the world than history had yet seen for nothing more than financial gain.

Oh and now we move on to the worst record in human history in terms of how humans have treated other humans.  The 20th century saw more bloodshed than all previous centuries combined, or so I've heard.  Was it in the name of religion?  No, rather, it was in the name of secular, materialistic philosophies such as facism and communism.  We see the blatant attempt at exterminating an entire race of people, along with anyone else not meeting an atheistic conception of the perfect man as well as those who would stand up for the targets of extermination (namely, members of organized Christian religions).  Let's also not forget the bequeathment of that philosophy that so many rational, liberal, academic people coddled--communism.  Far more have been killed in the name of that philosophy than Hitler ever dreamed of (well, maybe he did dream of it).  Both of these philosophies are completely divorced of Christian religious power. 

Now, who is it that is seen as probably the most influential person in bringing communism to an end?  Many say it was John Paul the Great.  In many documentaries and commentaries following his death, none especially Catholic in name or nature, I heard of his unwavering resistence to communism and the dramatic role he played in its fall. 

And so we see the true nature of religion:  arguably the most organized religion in world history has consistently tried to act as a check to the powers of this world, reminding them of their duties to mankind and trying to enforce those duties when it could.  The worst periods of violence in human history were made possible by the utter elimination of this religious power, the only power that strives to act in the name of something higher than itself, the only power that truly believes (and has a basis for believing) that we, as humans, have distinct and undeniable dignity and rights that flow from an Absolute Source.

So the next time you're tempted to diss religion, think on these things.  The next time you are tempted to laugh or cheer when somebody takes a pot shot at organized religion, think again.  Religion, if one approaches history with an open mind, has a track record of an undeniably positive effect on human nature, both on the individual and in public life.  The facts are there folks if you're willing to see them.  As Jesus said, "he who has ears to hear, let him hear."

Wednesday, 26 April 2006 01:51:34 (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [3]  | 
# Monday, 24 April 2006

Not long ago, I polled subscribers as to what they're interested in.  There seemed to be a fairly even divide between what I'll roughly call Technical posts and Non-Technical posts.  In fact, my goal with this blog is to be a blend of those two general categories.  At the same time, as much as it hurts to admit it, I know that some folks really don't care about my opinions on non-technical matters.  So it struck me (some time ago, actually; I've just been lazy) to create two general categories using the creative taxonomy of Technical and Non-Technical. 

Why?  This is because dasBlog (and most other blog systems, I imagine) allow you to subscribe to category-based RSS feeds as well as view posts by category.  So from this day forward, in addition to the more specific categories, I'll be marking all posts as either Technical or Non-Technical.  If all you care about is one or the other, you can just subscribe to one or the other and never be bothered with the stuff you don't care about.

You can view/subscribe to the feeds using the feed icon next to each category in the list (of categories).  Here are direct links as well:

Technical

Non-Technical

I hope this helps!

Monday, 24 April 2006 10:28:33 (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [0]  | 

In a recent post, I mentioned the acronym OPC, meaning "Other People's Code."  Somehow I doubt I'm the first person to use the acronym, so I don't intend to claim it as my own.  I can't say I've seen it before, but it seems so obvious that it should be one because OPC is so prevalent and we should all be talking about OPC much more than we do.  In an industry that arguably values reuse over every other virtue, you'd think that OPC would have long been canonized.

Yet it seems to me that when most people speak of reuse, they mean Their Own Code (TOC, I love overloading acronyms!) or, from their perspective, My Own Code (MOC).  In essence, they want other people to reuse their code, but there ain't no chance in heck that they're going to use OPC as a means to achieve the ultimate goal.  I want MOC to be reusable.  How can I impress my friends by writing code that can be reused by as many other people as possible?  This is something I think most of us that strive to be great at software think at one point or another, perhaps not in so many words, but ultimately, there is a sense of great pride when you polish off that last speck on your chrome-plated masterpiece, showing it to your buddies or the world in general and saying "that's MOC." 

The funny thing is that more often than not, the really ardent software folks among us, and even the less ardent, have a predilection for the NIH syndrome.  It's because we're all so damned smart, right?  Surely, those other folks at NIH Co. couldn't possibly have done it as well as I could have!?  Of course, we've got all the rationalizations lined up for when the business folks ask:

1) "I can't support that because I don't know it--I need the source code."
2) "You know, it won't meet our needs just right, not like I could do it for you custom."
3) "How much?  Geez.  I could write that in a day!"
4) "It's not using X, which you know is our preferred technology now."
5) "Did they promise to come work here if they dissolve the company?  I mean, you're just gambling on them."

And the list goes on.  We've probably all done it; I know I have.  Why?  Because, as one developer friend once put it (paraphrased): "I love to invent things.  Software is an industry where you get to invent stuff all the time."  In other words, we're creative, smart people who don't feel that we're adequately getting to express our own unique intelligence unless we write the code ourselves.

And now we finally come to what prompted this post.  I recently looked over an article by Joshua Greenberg, Ph.D. on MSDN called "Building a Rule Engine with SQL Server."  I'm not going to comment on the quality of the solution offered because I hardly think I am qualified to do so.  What I was completely flabbergasted by is the total omission of the rules engine being built into Windows Workflow Foundation.  Surely someone who has put that much thought into the theory behind rules engines, which, as is mentioned in his conclusion, are probably best known in workflow systems, would be aware of WF's own?  Surely one of the editors at MSDN Mag, which has done numerous articles on WF, including one on the engine itself published in the same month, would think it worth noting and perhaps comparing and contrasting the approaches?

Now, I don't want to draw too much negative attention to the article or Mr. Greenberg.  He and the editors are no more guilty of ignoring OPC than most of us are.  It is just a prime example of what we see over and over again in our industry.  On the one hand, we glorify reuse as the Supreme Good, but then we turn around and when reusable code (a WinFX library, no less!) is staring us in the face, an SEP field envelops reuse, enabling us to conveniently ignore OPC and start down the joyous adventure of reinventing the wheel.

This has got to stop, folks.  I'm not saying that this ignorance of OPC is the primary cause of the problems in our industry (I happen to think it is only part of the greater problem of techies not getting the needs of business and being smart enough to hide it).  But it is certainly one that rears its ugly head on a regular basis, as we guiltily slap each others' backs in our NIHA (NIH Anonymous) groups.  We have a responsibility to those who are paying us and a greater responsibility to the advancement of our industry (and ultimately the human race) to stop reinventing the wheel and start actually reusing OPC.  I'm not saying there is never a justification for custom code (God forbid!), but that custom code needs to be code that addresses something that truly cannot be adequately addressed by OPC. 

There will always be plenty of interesting problems to solve, which give way to creative and interesting solutions.  Just imagine if all this brainpower that goes into re-solving the same problems over and over again were to go into solving new problems.  Where would we be now?  Now that's an interesting possibility to ponder.

Monday, 24 April 2006 10:21:02 (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [2]  | 
# Tuesday, 18 April 2006

I just ran across a new feature of .NET 2.0 that's pretty nifty if you've ever had a need for it.  They have a new attribute, InternalsVisibleToAttribute, that allows you to tell an assembly who its friends are.  This feature, as you might imagine, is dubbed friend assemblies, and it means what it sounds like--friend assemblies can access internal code in the assembly that the attribute is applied to.  This is particularly useful in two scenarios I've run into:

1) You want to easily unit test internals.  Yes, there is some disagreement as to whether that's the right way to test things, but at least you can do it if you need to (and in my experience, you occasionally do).

2) You've neatly packaged code in separate assemblies that are related and need internal access but make sense to be packaged separately.

It seems like kind of a hack, but I think it is a nice one.

Tuesday, 18 April 2006 22:25:35 (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [0]  | 
# Monday, 17 April 2006

I've been running XP 64 on my new box for a few weeks now, but I've managed to get by thus far without tweaking IIS much.  I was pleasantly surprised when something wasn't working that required the ASP.NET process identity to have write access (dasBlog).  I immediately went to the dir and added ASPNET w/ modify perms on the dir and still got the permission denied error.  So I went back into IIS and lo and behold, it was running IIS 6.  Too cool!

Of course, you may be wondering how I managed to overlook this fact for so long.  It is because I just assumed that it was just running the IIS 6 Manager client.  I usually install that on my XP boxes because I like the updated interface, and it allows me to connect to 2003 IIS servers.  So it didn't phase me at all to see the IIS 6 client.  Somehow I managed to get by without noticing that it was in fact running IIS 6. 

So I just changed the user with write access to Network Service and voila!  Pretty snazzy.  The point is to let you know that if you want IIS 6 with XP, one option is to go out and buy 64 bit machine and run Windows XP 64 on it.  :)  I can tell you that it has a few quirks, but most of them you can work around.  I've not had to boot to my 32bit dual boot at all.  So if you're in the market for a new machine, you should definitely consider 64 bit.

Monday, 17 April 2006 14:44:37 (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [2]  | 
# Thursday, 13 April 2006

I'm very happy to announce that I'll be joining Infragistics soon.  Officially, my first day will be May 15th; however, I'll be going to the Alabama Code Camp to represent them next weekend (4/22).  If you're in the Huntsville area, you should definitely check it out; there are tons of great speakers and sessions lined up.  (Mine's not up there yet as it is still undecided which of the ones I submitted I'll be doing.)

Anyhoo, I'll be working for Infragistics as their Codemunicator, a title that they let me coin because the position is kind of a blend of things.  Codemunicator is a portmanteau, as you might guess, from "code" and "communicator."  It sounds like it'll be a lot of fun; I'll get to do a number of things that I enjoy--writing, designing, coding, and even the occasional speaking from what I hear.  And I'll get to work with great guys like Jason Beres (noted author and INETA speaker), Devin Rader (also noted author and ASPInsider), and others whom I've had the pleasure to meet. 

Plus, some other really cool peeps are not far away, like DonXML (MVP and XML extraordinaire), Scott Watermasysk (Mr. .Text himself, ASPInsider, MVP, etc.), Doug Reilly (author, ASPInsider, MVP, etc.), Terri Morton (author, ASPInsider, MVP, etc.), DotNetDude (author, INETA speaker, MVP, etc., though I hear rumors of his not being long for the area), and I'm sure I'm not aware of or forgetting others and/or not getting all of the accolades right (that's my official apology if that's the case).  So all I'm saying is it's a really cool area for .NET experts and ubergeeks. :)  Hopefully we can all get together occasionally for dotNetMoots of some kind.

Of course, this change in employment constitutes a change in locale for me and my family.  We'll be moving from sunny Tampa, FL up to Princeton, NJ (right near East Windsor, home of Infragistics HQ).  I'm sure a lot of folks think such a move is crazy, but the wife and I are not especially keen on the six-month summers down here in Tampa.  We both grew up in cooler climes that have all four seasons, so we're actually looking forward to having them again.  That's not to say that the Tampa area doesn't have lots to recommend it, most notably family, friends, and mild winters, but we still feel this is the right move for us.

We've heard a lot of good stuff about the area we'll be in, both from folks who live there now and who lived there in the past.  Apparently, the whole "armpit of the US" epithet only applies to the Newark/Elizabeth area (in the NE near NYC), and having flown into and out of Newark and driven by Elizabeth, I can believe that.  (No offense to anyone who lives there and likes it!)  But central NJ is actually quite nice from what we saw when we toured the area a bit and from what we've heard.  It's about an hour by train from NYC and Philly, not far from some mountains in Pennsylvania, and not far from the beach and Atlantic City, so we're actually looking forward to it a lot.

All in all, we're pretty psyched about the move, and I'm especially juiced about going to work for a great commercial software company like Infragistics.  They still have openings, so if you think any of them sound interesting, let me know.  I'd love to have more good people come on to work with us.  If any geeks or ubergeeks live in the area and read my blog that I don't know about, give me a shout out.  I'll be helping Jason Beres et al pump up the NJDOTNET user group, so join and come if you're in the area.  You WILL join and come! <waves hand using Jedi mind trick>

TTFN!

Thursday, 13 April 2006 22:13:08 (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [9]  | 
# Tuesday, 11 April 2006

Do you find yourself being overwhelmed by the amount of email flowing into your inbox?  Here are some tips I've used to keep my inbox nearly empty over the years.  And most of these tips extend to your real-world and voicemail inbox as well and will (I think) help you remain more sane and organized (and polite).

1 - Do not subscribe to email lists that you are not actively interested in.  This seems obvious to some people, but if you find yourself just deleting every message from a particular email list, newsletter, or other source of emails, just unsubscribe.  Maybe you were really keen on the particular subject at the time you subscribed; maybe you thought it'd be neat to stay on top of X, but if you find that's just not the case--that it's not important enough to you to do so, just cut it out; you can almost always subscribe again later if you get interested.

2 - Think of your inbox like a to-do list; it already is in a certain sense, but make it more formal in your head.  Anything in your inbox needs attention, and it needs it as soon as you can get to it.  The reason this is helpful is that it can help motivate you to not let things pile up.  It also lends towards other helpful things like the next tips.

3 - Try to take action on every email as soon as you read it.  If it requires a response, try to respond right away.  If you need to think on it, it's okay to leave it there for the next pass.  If you think it will be a while until you can respond like you think you need to and the missive is personal (from a real person to one or few persons), respond right away saying you're thinking about it and give a timeframe within which you intend to respond.  This is just polite and will probably save you from getting more emails from that person asking for a status.  If it is something from a list or newsletter that you are interested in, leave it there for the next pass.

4 - I mentioned the next pass in the previous tip.  This is simply a way of further weeding out your inbox, especially for non-personal emails.  If you truly didn't have time to properly take action on the first pass, the next time you sit down to look at your email, give everything a second look.  This takes far less time, typically, than the first pass, and allows you to quickly determine if you feel you can take action on the second pass items.  By the second pass, you should have taken action on 80% or more of the emails in the previous first pass.  Yes, I'm making the percentage up, but I'm just pointing out that if you're finding most emails in the inbox survive the second pass, you're probably not devoting sufficient time to it.  .NET developers can liken this process to .NET garbage collection, if emails survive the first pass, they're promoted to gen1, and so forth.  But the higher the generation, the fewer remaining emails there should be. 

5 - Aggressively delete.  Be willling to decide that you just are not going to get to something and either file it away or, preferably, delete it.  This only applies to non-personal emails that don't require a response (e.g., the newsletter/email list variety).  You may think that you'll get time some day to look at it, but I assure you, if it reaches the third pass and is still not important enough to make time for, you probably never will make time for it.  In my opinion, the only things that should survive the third pass are items that truly require action on your part but that may require more time than the average email response.  For instance, if you get a bill reminder, you can't just choose to delete and ignore that, but you may not have time until, say, the weekend to get to it.  It's fine to just let these lie, but leave them in the inbox so that you don't forget.  You should have very, very few emails that survive the third pass.  If you have lots, you're not giving your email enough time.

6 - I should mention that in the last three tips, there is implied prioritization.  In my book, emails from one person directly to you should always take precedence, even if you're not particularly keen on it (e.g., if someone is asking you for help, which happens for folks like me who publish helpful stuff).  I consider it rude to ignore personal emails, even from recruiters, so I always make an effort to respond, if nothing else than to say that I'm sorry that I don't have time.  To me, this is just common sense politeness, and I hate to say it, but it really irks me when folks don't extend the same courtesy to me.  The good news is that if you follow my tips, you can continue to be a polite person, at least in that regard, because your inbox never gets so full that you don't have time at least for the personal emails.  (And by "personal" I don't mean non-business; I mean from a real person to a real person, so business-related missives are not excluded from this rule.)

7 - Check your email proportionately to how often you get personal email.  It's okay to let newletters and lists pile up because you can safely delete huge swaths of those if they get piled up, but it is not okay (IMO) to let personal emails pile up.  If that's happening, you need to check email more often and/or make more time for it.  Maybe it's not your favorite thing, but it is just part of life.  If you're important enough, get someone to screen your emails for you.

If you follow these guidelines and still find your inbox piling up, you're either really, really important and famous, or you're just not being honest with yourself about what you do and don't have time for.  If nothing else, find a way to stay on top of the personal email.  Even if you don't like my approach to everything else, it is just the polite thing to do.

Tuesday, 11 April 2006 21:45:11 (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [0]  | 

At the recent Orlando CodeCamp, I did a presentation called (roughly) "Introduction to Generic Database Programming with ADO.NET 2."  Phwew.. gotta take a deep breath after that one.  So, the premise of the talk was to introduce folks to the features in ADO.NET 2.0 that make provider-agnostic (a.k.a., generic) database programming possible.  And I think that was accomplished in that it covered the System.Data.Common namespace and had an example that illustrated how to create connections using the DbProviderFactories class and the provider invariant name as well as how to retrieve metadata information using the GetSchema methods on DbConnection.

In my chapter for Professional ADO.NET 2, I created a very basic custom ADO.NET provider for Active Directory, which required me to implement most of those classes and provide the basic info from GetSchema.  So I was familiar with it from the theory side of things and thought it was pretty neat as an idea.  But I personally have not had the opportunity to really dig into doing it much myself; I prefer using an object-relational mapper when I can, and I've been fortunate enough to not be in too many situations where doing "real" generic db programming was necessary.  I also knew, in theory, that there were complications in creating database-agnostic code, but I didn't know just how unfinished it is.

Consider, for example, that Oracle returns results from stored procedures using an output cursor parameter instead of a regular result set; this can make it less than generic when you want to use sprocs.  And even something as simple as dynamic SQL command parameters is not fully addressed with the new ADO.NET 2 stuff.  It is this fact that prompted this blog entry.  I was trying to do something super simple--create a very focused test data generation tool that could use Oracle or SQL Server as its persistent data store. 

In particular, for the commands (trying to follow best practices), I was going to use ADO.NET parameters instead of string concatenation or substitution, and I recalled that one of the new standard schemas is a DataSourceInformation schema that specifies, among other things, a format string for parameter names.  In other words, as my friend Plip demonstrates on his blog, I should be able to use that value with String.Format in order to get a properly-formatted parameter name for my commands.

It turns out, though, that it just don't work, at least not in the RTM version.  (In Plip's defense, that post was made when Beta 1 was current.)  In the RTM, the SQL Server provider returns simply "{0}" as the parameter marker format string, which is, I'm sad to say, utterly useless.  It should return (in my humble opinion) "@{0}" to prepend the @ in front of the name as that's what SQL Server expects.  Looking at the Oracle provider, it correctly prepends the : using ":{0}" as the format string.  So, something that should be as simple as getting an appropriate parameter name is goofed up. 

Now maybe I'm missing something, but I know that folks like Frans Bouma, who have far more experience than I writing code to interface with multiple providers, seem to indicate that my impressions are not far off.  My own object-relational mapper completely abstracts the SQL itself such that providers have to supply SQL templates, so I'm not faced with writing generic SQL and can still take advantage of the abstractions provided by ADO.NET.

So I guess it really depends on what you're looking for when you say generic database programming.  For now, it seems only partially fulfilled, particularly since the queries themselves don't have sufficient standardized abstractions (that I'm aware of anyways).  I know there is a SQL standard, but as far as I can tell, it is fairly limited and doesn't cover simple things like (as Frans pointed out) getting an db-generated identity value back.

The good news is that there are good abstractions that can take care of a very large portion of the provider-specific work for us.  Obejct-relational mappers are one such example, and with the advent of LINQ and DLINQ, I hope that we'll find less and less need to actually write SQL ourselves and rely, rather, on these higher-level, object-oriented abstractions to hide the complexities of data persistence for multiple providers.  Generic database programming isn't a myth; it's just a legend, something based in truth but not a full reality.  What do you think?

Tuesday, 11 April 2006 20:26:01 (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [0]  | 

I just spent a few hours diagnosing what appears to be a bug in the new ListBindingHelper class used by, among other things, the Windows Forms DataGridView control.  If you call one of the GetListItemProperties methods, as the DGV does when automagically determining the columns based on your data source, it may ultimately call a helper method called GetListItemPropertiesByEnumerable.  This is a last ditch attempt to determine the properties based on the type of objects in your data source. 

Well, actually, it is the second choice; it will first look to see if your list class implements ITypedList and let it take over the work of getting the properties, but if your list class is one of the handy ones in the framework (an array, ArrayList, List<>, etc.), it will fall back on the GetListItemPropertiesByEnumerable method, assuming your list class implements IEnumerable, which most do (as an aside, it will then just get the properties on your list or, to be more precise, whatever the heck you passed into the method).

So the bug (or so I call it) is in that method.  I presume in an effort to be all high-performing and such, the developer wrote in a killer short-cut:

Type yourEnumerableListType = yourEnumerableList.GetType();
if (typeof(Array).IsAssignableFrom(yourEnumerableListType))
  return TypeDescriptor.GetProperties(yourEnumerableListType.GetElementType(),
           ListBindingHelper.BrowsableAttributeList);

Note that I took liberties of paraphrasing here, but if you know how ICustomTypeDescriptor works, you'll readily see the problem here.  You see, it works on instances, not types.  This means that your implementation of ICustomTypeDescriptor will never be called if you are binding an array, even if there are valid instances in the collection upon which it could be called.  I see this as a major bug, and I'm quite surprised it made it through QA.

You see, if your enumerable list class is not just a plain-Jane array, it will fall through that short-cut down to what it really should be doing, which is getting the first item from the enumerable list and calling TypeDescriptor.GetProperties (the object-based one), which will call your implementation of ICustomTypeDescriptor and allow you to substitute a property list of your choosing.

Now, there are certainly plenty of workarounds for this, and in fact, I wouldn't have run across it if it weren't for the fact that someone else wrote this method to return an array instead of (e.g., an generic List).  But that's not the point; the point is that it shouldn't be doing this.  If there are objects in the enumerable list, it should interrogate them, regardless of whether or not it is an array.

In any case, whether or not you agree with my classification of this as a glaring bug, I hope that maybe someone will benefit from the time it took to research this gotcha (because it most definitely is that).  The short answer, though not the ideal, is to just not bind to arrays and use either an ArrayList or generic list or collection or whatever.  And, by the way, if you're wondering how I figured all this out, there's a nifty little tool called .NET Reflector that provides many insights.  It's not as easy as debugging (because you can't actually step into the code), but if you're good at reading and following control flow, it can help you gain a much deeper insight into OPC (other people's code) when the docs just aren't sufficient.

Tuesday, 11 April 2006 19:00:02 (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [1]  | 

Disclaimer
The opinions expressed herein are solely my own personal opinions, founded or unfounded, rational or not, and you can quote me on that.

Thanks to the good folks at dasBlog!

Copyright © 2017 J. Ambrose Little