Wednesday, June 29, 2005

The last several weeks have been insane in terms of business (as the two readers that follow my blog might be able to attest), but the 20 hr days haven't posed an impediment at getting work done around the house.  Last summer I built a shed from scratch in my backyard.  Well, (finally) we got around to putting siding on it to match the house and I must say it looks fantastic!  I've included a 'before' and 'after' picture below from slightly different vantage points.  I'm very happy with how it turned out.

Additionally, we bit the bullet and replaced our garage door on the house with a door from Martin Door.  We got the works (fully insulated, whisper quiet opener, powder coated tracks, weatherseal, windows, and all the upgrades), plus it matches the shed in the back yard.  It's wonderful to be nailing out these projects.

I have four outstanding projects now that I must finish this summer - preferrably in the coming weeks but we'll have to see how much is humanly (and walletly) possible.

  • Finish the basement.  I've built out a very cool office and home theatre downstairs, but I still have to put in the drywall and finish it up, but we've already purchased the hardwood flooring for the office.
  • Sand/Oil the deck.  Last summer I designed and had built a deck in the backyard out of iron wood.
  • Enclose the front porch in a brick wall w/columns and lights.
  • Paint the garage floor

Looks like I have my work cut out for me, but it'll be rewarding and nice to have it all done.  I'll post up pictures when I finish the various projects.

Shed before:

Shed after:

Garage and Shed:

Wednesday, June 29, 2005 6:06:00 AM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Monday, June 27, 2005

Ok, so this makes for two non-programming-targeted posts (the last one was pretty stupid, I must admit), but I can't quite make out what the real intentions of the author was.  I understand that English is not the easiest of languages to speak or translate to from another tongue (far too frequently things get trans-literated often to hilarious results), but this case doesn't seem to make sense.  When you click on the site's 'prices' link this message pops up.  Can anyone help me out?

Monday, June 27, 2005 5:36:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Thursday, June 23, 2005

Today I was contemplating the universe and stumbled upon a quandary.  We as humans have associated terms with the social structure and organization of the various creatures in the animal kingdom.  For example, wolves travel in packs whereas cows meander in herds.  What is the appropriate term for a group of gremlins?

Is it a...

...pack of gremlins?
...herd of gremlins?
...gaggle of gremlins?
...flock of gremlins?
...pod of gremlins?
...school of gremlins?
...swarm of gremlins?
...litter of gremlins?
...gang of gremlins?
...legion of gremlins?

(Obviously my thoughts don't run too deeply...)

Thursday, June 23, 2005 4:10:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [1]  |  Trackback
 Sunday, June 19, 2005

If you're like me, you have created a few web pages/sites in your time.  Some, if not most, of these require some level of authentication (be it Forms Authentication or Windows Authentication (Integrated Security)).  Oftentimes, the website you create resides on the local machine and you can simply browse to it via http://localhost, but such is not always the case.  You may have been occasionally perplexed that when you use Windows Authentication that the browser (Internet Explorer) will prompt you for your user name and password.

Shouldn't it already know who you are, since you're already authenticated to the domain?  Well, the answer is yes, it knows who you are, but it doesn't care in certain circumstances.

If you browse to http://localhost or http://MyComputerName to a website using Integrated Security, IE will automatically provide credentials to the webserver and thereby not prompt you.  However, if you use the FQN (Fully Qualified Name) of your machine (e.g. http://MyComputerName.Domain.local), IE will prompt for a password - even though it's the same machine, the local machine no less.  The primary reason behind this is the punctuation...period :-).  In fact, IE will consider dotted URLs (those that contain periods) to exist in the internet zone.  Because that zone is more hazardous and less trusted than the intranet zone, credentials are not automatically provided.

You can circumvent this issue by adding the URL to the Intranet Zone:

  1. Click Tools -> Internet Options
  2. Select the Security tab
  3. Select Local Intranet and click the Sites button
  4. Click Advanced
  5. Add the FQ URL (e.g. http://MyComputerName.Domain.local)

There are other factors to consider besides just the dotted name.

  • The browser must be IE (duh, it's the only browser that supports Windows Integrated Security)
  • The site must be set up for Integrated Security (if anonymous is enabled, Integrated Security will have no effect)
  • Automatic logon only in Intranet zone must be enabled

For more details, check out the Microsoft documentation.  This took me a long time to find.  I have long suspected that the periods in the name were causing the issue, but had never seen this documented until a few days ago.  Anyway, it's good information to know.

Sunday, June 19, 2005 4:35:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [1]  |  Trackback
 Thursday, June 16, 2005

I have an archive folder on a dedicated drive in which I store 'clean' Virtual PC images.  These images are the baseline install (+Patches) of the various operating systems I run (e.g. Windows XP, Windows Server 2003, et al).  When creating a new virtual PC (something I do quite frequently), I'll copy out one of these clean images into a 'working' folder, rename it and mount it as a virtual machine.

You can quickly run into issues when doing this however as there are a variety of things that can crop up later as you go about using them.

  • Machine names will not vary, until you change them.  It's a little crazy to have 5+ VPC's all with the name WIN2K3 running around.
  • SID's will not vary.  This is particularly important when you create a private domain of copied VPC's.
  • Network settings.  You have to be careful how you set up your private networks or you will run into issues.

If you're making multiple copies of a single VPC and you want to create your own little domain, here are a few tidbits that might be helpful to you in establishing it properly.  Note, I've only really tested these guidelines on a Windows Server 2003 domain, so you're on your own.

  • If you've already created a domain controller from a VPC clone and you want to rename it, you'll need a tool called netdom.  This utility is included in the \Support\Tools directory on your Windows Server 2003 disc.  Then to rename a domain controller, follow these steps:
    • Make sure the domain function level is Windows Server 2003 (in Active Directory Domains and Trusts)
    • Open a command prompt
    • Enter netdom computername [CURRENTCOMPUTERNAME] /add:[NEWFQDN]
    • Enter netdom computername [CURRENTCOMPUTERNAME] /makeprimary:[NEWFQDN]
    • Reboot the server
    • Open a command prompt
    • Enter netdom computername [NEWFQDN] /remove:[PREVIOUSFQDN]
  • Before you join the domain of VPC's, you should change the SID of each participating VPC.  The easiest way I've seen to accomplish this is to download a small utility from www.sysinternals.com called NewSID.  This utility allows you to alter the SID of the computer by randomly generating a new one, copying the SID off of another machine, or specifying it manually.  Very cool!
    • Note, you can join the domain even if you don't change teh SID but it's pretty useless.  When you attempt to login to the domain you will be presented with an error message resembling: The name or security ID (SID) of the comain specified is inconsistent with the trust information for that domain.
  • Don't forget to follow the guidelines I alluded to before in establishing your network.  Once you have it set up, it works pretty flawlessly!

Good stuff.

Thursday, June 16, 2005 1:18:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [1]  |  Trackback
 Wednesday, June 15, 2005

Today, we held our June .NET User Group meeting.  It was great!  Unfortunately due to very late speaker cancellation and other scheduling issues we had to move our meeting from our usual last Thursday's meeting.  David Waddleton, an MSDN Events Team member out of Houston was in town and offered to present to our group a few weeks ago.  Boy! Talk about the stars aligning.

David spoke on Advanced Web Services and touched on quite a few topics that are of interest.  Primarily, he focused on WSE and demonstrated taking what would normally be an unencrypted, insecure SOAP request to a web service and tagged on the Web Service Extensions to encrypt the contents and in essence make the same request to the web server, getting the same results, but in a secure manner.  David also touched on SQL Reporting Services and Http end points in SQL Server 2005.

All very cool stuff.  I was very impressed as well with the turnout.  We had 50+ people there which was unexpected but very welcome!  We had some great giveaways as well: a few SQL Server Standard licenses, Sax.Net Communications Library, Primal Code, and much more.

Thanks go out to the user group members and their support!  What a fantastic user group!

Wednesday, June 15, 2005 2:51:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Monday, June 13, 2005

Last week, while at Tech Ed, Orlando, I made a post regarding a few feelings around “Code Generation” and “ORM”.  It was an intentional move on my part to solicit some discussion and see where people stood - and I got some very good and insightful comments!

While not really technically related, I kinda view Code Gen and ORM in the same light and I can really appreciate them.  When I say that I don't quite subscribe to their precepts and concepts I do not insinuate that I don't see a place for them nor understand their importance.  And yes, I too feel that Scott is an excellent developer and has some really insightful perspectives on things and a very deep understanding of many aspects of software development.  My previous commentary was, in no way, any disrespect to him, but rather a perspective on somes issues that were discussed.

When presented with a pattern, practice, concept, or a principle which I don't currently implement, I generally take a reserved and cautious view initially (this applies in everything - from software to my personal life).  I am not one to jump on the bandwagon simply because 1, 2, 50, 100 or even 10,000 people say it's right.  If I did that, I'd just be going with the flow, following the stream of jargon simply because something is deemed as cool or modern, and not making my own decision based on my own understandings, experiments, and/or implementations.  Sometimes the old school teachings and principles still have merit.  Majority doesn't make something right, it just makes it popular.

Then again, I'm not saying that neither Code Gen nor ORM are 'wrong' per se, I'm simply stating that I don't currently implement them in my development process to the extent that others do.  This isn't because I love CRUD programming, but because I take a slightly different approach to writing software.  I hope to explain a bit more below.

Code Generation

Of the two, I am more reserved about code generation.  Sure, writing boilerplate code is pretty tedious, repetitive, prone to errors, and much more, but how often is data access code truly boilerplate?  If all your code is doing the same thing (e.g. creating a connection, opening it, running a command, disposing of resources, etc), perhaps you should revisit that.  It might be helpful to have some centralized data access module or library.  Then again, if you do that, one could argue that it's more the case where code gen is feasible, and I can understand that too.  As I see it, the most boilerplate code would exist not in a DAL (because of library autonomy), but in domain objects where properties map more directly to data fields and the properties are simply getters and setters to an underlying field.

There sure is a tendency within the industry to promote code generation and it's definitely not lost on Microsoft.  In fact, as Matt mentioned in his comment earlier, there are several new enhancements in the VS 2005 timeframe that really seem to promote this: DSL Tools, GAT (Guidance Automation Toolkit), Software Factories, and partial classes.  Things which are frankly pretty awesome!

I believe that there is an inherent brittleness in code-generated objects.  Business requirements change.  Data storage mechanisms change or vary between objects.  Actions pertaining to object vary widely.  I would be lying if I said that all my business and/or data objects behaved the same.  I find myself decorating classes with attributes (e.g. GuidAttribute, ClassInterfaceAttribute, SecurityRoleAttribute, DescriptionAttribute, and many more) that vary on a class-by-class basis or a method-by-method basis.  Almost ALL of my programming is interface-driven programming (especially when I'm creating EnterpriseServices-based (COM+) classes).  There is code within each method that validates parameters passed from the business tier, performs operations on them, calls stored procedures, builds objects, and much more.  The stored procedures also validate data, update multiple tables, call other stored procedures, and much more.

I can't see these objects being generated automatically for me.  Far fewer than 5% of my procs are as simple as SELECT ID, Name FROM Customer or UPDATE Customer SET Name = 'xxx' WHERE ID = x or DELETE FROM Customer WHERE ID = x.  Were that the case, I'd have hundreds upon hundreds of stored procedures that all look alike, are not maintainable, and don't really buy me anything.  I could simply use ad hoc queries instead.  Additionally, each stored proc has security settings, permissions granted to specific applications and/or users.

The VAST majority of my procs are actions that are performed on the domain objects such as 'Complete Task' or 'Place Order'.  I cringe at having to retrieve a Task object, setting its Completed property, and then calling Update to save it to the data store - such a method might require a bunch of business logic to run or a multi-step database operation.

Perhaps code generation is more template based than I'm willing to let on.  Template-based code generation, in my mind, has must more merit and is much more attractive than what I'll call 'reflective code generation'.  I have seen some really fantastic XSD-based and WSDL-based templates that DO allow for some pretty tight classes to be generated (something that Scott did illustrate in his presentation)...I will be looking into that more here in the future.

All said, however, I truly see a use for code generation and will probably employ it in the very near future.  Heretofore, I could not honestly get behind it 1) for fear of losing any tweak or change I made the next time the code is regenerated and 2) perceived lack of control over the resulting classes.  With the advent of partial classes in .NET 2.0 I can really see its practical usage.

ORM

I tend to view ORM implementation in the same camp as Code Generation because of the tools that automate the creation of the objects.  The chief tenets behind ORM, however, I can definitely get behind.  Having some form of a 'mapper' class that can create, update, and manage domain classes is paramount to almost all development projects.

My object hierarchies don't frequently mirror my database relationships, though similarities often exist.  Generally speaking, I don't believe it's a good practice to push the database organization onto the business tier or the UI tier.  Sure, sometimes object hierarchies and relationships are understood and rather apparent (e.g. Customer -> Orders -> Order Details) and lend themselves to an object hierarchy, but that, in my mind, is an operation of the UI and business layers - I shouldn't have to knowingly navigate an object hierarchy to simply get the single order detail I want.  I should be able to go right to it if I want.  Likewise, when I commit a change, I shouldn't have to send an entire object graph to a data layer to have the entire thing analyzed to simply update a misspelling somewhere deep in the hierarchy.

Each application has its own solution, and for some ORM is the right solution; I tend believe it's more the exception than the rule.

Though I do practice several ORM principles in my code, I can't honestly say that it's pervasive, and it's not generated.  I can definitely get behind the ORM bandwagon more easily than I can the Code Generation one.  In the days to come I will be experimenting more with it to gain a deeper understanding and will report back with my findings.

Monday, June 13, 2005 6:45:00 AM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [9]  |  Trackback
 Saturday, June 11, 2005

I have a CAPTCHA control installed on this site and for the most part it's done a great job of filtering out spam comments on this blog.  Lately, however, I've been the target of some PingBack/TrackBack spammers and it's really driving me nuts!  I have to literally clear out 50+ a day.  Does anyone have any PingBack/TrackBack spam blockers they would recommend, or should I resort to creating my own 'black-list' plug in for .Text?

Thoughts?

Saturday, June 11, 2005 5:30:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [1]  |  Trackback

Well, I'm home at long last.  I have some wrap-up comments regarding Tech-Ed (which was a blast!) that I have yet to post, but I simply have not had a chance to do it yet.  It is so good to be home and start to settle into a more manageable and regular routine.  It's been so hectic lately that I've not really had a chance to work on anything that I want to work on or get anything done around the house (tasks which are far past-due it's not even funny).

I also will be addressing some comments that were made on my blog recently and will try to get to that tomorrow.  Thanks everyone for your continued support and encouragement!

Saturday, June 11, 2005 5:27:00 PM (Mountain Standard Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  |  Trackback