On this page.... RSS 2.0 | Atom 1.0 | CDF
# 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]  | 
# Sunday, 09 April 2006

Because of my pending interstate move, I spent some time yesterday going through my old electronic stuff.  I knew I had a few things I wanted to get rid of, so I got it all together.  Well, the next problem was what to do with it.  I knew I didn't just want to toss it out; not only would that be bad for the environment, but some of the stuff still works.  So anyhoo, I rattled around the internet for a bit, trying to find the best way to get rid of it.

Turns out, most orgs don't want my old electronic stuff any more than I do, so I thought maybe I could recycle.  Dell has a decent recycling program (you basically pay $10 for it), but you have to package it all up and ship it via DHL.  Not bad, but still involves cost and trouble.

I finally stumbled across freecycle.org.  It's basically a bunch of Yahoo groups, each specific to a particular area.  You can post your offer of free stuff on it, and folks will get back to you about it.  I thought, hey, this could work.  Pretty easy--just post a simple message.  So I did that, and within 10 minutes of the post being approved, I had five emails in my inbox from people wanting it.  I just picked the first that got there, emailed them, and they're picking the stuff up today. 

Totally awesome!  And it's not just for electronics--virtually anything you want to find a new home for (except for you or your children) can be offered there.  Now I'm just trying to figure out what else I can foist off on (err.. give away to) other people. :)  I thought it was cool enough that I wanted to spread the word; it's a great way to keep the land fills empty and potentially help others in the process.  You know how the old saying goes: "one man's trash is another's treasure," and this organization is the perfect proof of that.  So be green for free and go to freecycle.org to pass along your old stuff to others who really want it!

Sunday, 09 April 2006 15:44:27 (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [1]  | 
# Saturday, 08 April 2006

One of the great Florida.NET guys, David Silverlight, has put together a pretty nifty community site called Community Credit.  The tag line is "we give stupid prizes to smart people."  The basic gist of the site is that you can enter your community activities and, depending on what they are, get a certain number of credits/points.  Every month, the top N community folks get awarded with stupid prizes.  So if you're doing dev community work, go sign up and start recording your points.  Not only will it help you track what you're doing, it will also let others know what you're up to and, hey, you might just win something.

Oh and, yeah, I know, it's been around for a few months; I've just been too lazy to blog about it until now.  So sue me! :)

Edit: I forgot to mention, you should also sign up for the newsletter.  David's got a pretty good sense of humor, and I think you'll enjoy it.

Saturday, 08 April 2006 13:40:32 (Eastern Daylight Time, UTC-04:00)  #    Disclaimer  |  Comments [0]  | 

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