We recently decided that with the effort we're putting into our website and some changes that we're making that now would be as good of time as ever to make the switch to the new Asp.net MVC Framework.  We're no Google, but we're currently receiving around 18,000 unique visitors a day and 300,000 page views and hope to grow that number as we make our site easier to use for our customers.  I hope to rely heavily on Phil, Rob, and Scott for assistance if needed. 

The MVC design appeals to us because the large amount of business logic that has crept it's way into the codebehind.  Despite the best intentions, the current site, which is programmed in asp.net 1.1, has had too much logic to creep into presentational areas while running with webforms.  The biggest drawback to this is reduced testability.  Testability should be important in any project but for us it is paramount. We have business rules that if not adhered to amount to real-world fines:

A few years ago a customer bought some lubricant that is sold in an aerosol can.  Since 9/11 aerosol cans cannot be shipped as cargo on airplanes.  Somehow this order made it though the checks we have for this type of thing in the warehouse and made it onto the UPS truck.  At the UPS facility, a UPS employee heard something emanating from a box that sounded like an aerosol can.  At that point he is required by law to check the contents.  When he opened the box he found the aerosol cans.  Despite knowing us and our reputation, he was required to call the FAA and say something to the effect of, "I found some aerosol cans in a package that was scheduled to be flown."  It didn't matter that this was an accident or "just a few cans", we were still fined.  We were warned that if this were to happen again that we would face a fine somewhere in the low six figures. The FAA doesn't mess around.

As we go forward I plan to document on this blog the highs and lows of our transition.  I'll post questions and problems we're having that I hope you can help with as well as tips and tricks our team has found helpful.  Stay tuned as we make the transition.


 
Categories: .NET | MVC | Software

June 17, 2008
@ 03:05 PM

Compare the following two error messages and think about which you would find more helpful.  Then, the next time you are throwing exceptions with messages remember this post.

Error Message from Castle's Windsor IoC libraries:

Can't create component 'ProductService' as it has dependencies to be satisfied.

ProductService is waiting for the following dependencies:

Services:
- JPCycles.Framework.Services.IInventoryService which was registered but is also waiting for dependencies.

ControllerInventory is waiting for the following dependencies:

Services:
- JPCycles.Controller.IInventoryRequestInterpreter which was not registered.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: Castle.MicroKernel.Handlers.HandlerException: Can't create component 'ProductService' as it has dependencies to be satisfied.

ProductService is waiting for the following dependencies:

Services:
- JPCycles.Framework.Services.IInventoryService which was registered but is also waiting for dependencies.

ControllerInventory is waiting for the following dependencies:

Services:
- JPCycles.Controller.IInventoryRequestInterpreter which was not registered.

Error Message from .NET framework:

Object reference not set to an instance of an object.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.

 
Categories: .NET | Programming | Software

"But you have the source!"

I heard that statement a little over a month ago at the Alt.Net Open Spaces event in Seattle.  It's no secret to those who know the community, that open source technologies are at the very least promoted and in many cases you'll find many open source project committers within the Alt.Net community.  Heck, David Laribee, a founding member if there is such a thing, in a post defined Alt.Net as (emphasis mine):

  1. You’re the type of developer who uses what works while keeping an eye out for a better way.
  2. You reach outside the mainstream to adopt the best of any community: Open Source, Agile, Java, Ruby, etc.
  3. You’re not content with the status quo. Things can always be better expressed, more elegant and simple, more mutable, higher quality, etc.
  4. You know tools are great, but they only take you so far. It’s the principles and knowledge that really matter. The best tools are those that embed the knowledge and encourage the principles (e.g. Resharper.)

The quote, and many like it, came in a session titled "Mature Open Source projects versus first generation Microsoft projects".  The discussion centered around why some (many) developers, managers, and executives feel comfortable choosing a brand-new Microsoft product when a far more mature open source alternative exists.  One the fears surrounding the adoption of open source is the lack of surety that open source project will exist in perpetuity.  One needs to look no further than two projects, NVelocity and NDoc, to find historical evidence of an open source project vanishing.  The main counter-point to that argument, and many others, was the quote above, that with open source, you were never truly left high-and-dry, since you had the source.

It's a noble thought, but really, who wants to manage another codebase in addition to their own?  In fact I turn to open source project many times so I don't have to write my own code.  Why re-invent what someone else has already done and guided to maturity?  The idea that I can compile and manage another, possibly large, and probably complex codebase is hardly a comfort to me.  It wasn't until a few weeks ago that I realize that the open source pundits were correct.

I have been working on a project for the last year that has, as of two versions ago, started using Watin to automate the downloading of a file from the internet.  Watin is a testing framework but is used by many to automate business processes, which is what I use it for.  If you haven't checked it out yet, it's beautifully simple.

Watin provides handlers to download a file, however, the code was hanging at the point where it should've cleared the download.  I looked at every documentation page, blog post, and blog comment I could to see if I was missing something.  My usage was correct.  So I dug in a bit further using WinDowse to find the handle of the button that should be clicked.  As it turns out the handle of the Save button in a FileDownload Dialog changed from 4424 to 4427 in IE7, who would've guessed it right?  Well, since I had the source I went in and made the change, and voila, I'm back in business.

It gave me some confidence that if an open source project does cease, I can pick it up and patch it up.  I still don't want to manage multiple codebases from many different source, but in the end the pro open-source guys were right, "You have the source!"


 
Categories: .NET | ALT.NET | Musings | Open Source Software | Software

May 10, 2008
@ 03:49 PM

imageLast year when I built a new machine I purposefully built the machine with lots of power so that I could have multiple different environments and insulate myself from the loads of crap-ware that inevitably ends up on my machine.

Virtual machines allow me to download and try some utility in a sandbox where I know I can return to a previous state.

I opened one of my virtual machines and saw the screen posted on the right.  If this were on my host machine I think I'd need a new pair of underwear.  I don't have the time to rebuild a machine and so screens like the one of the right scare me.  However that is a virtual machine that had the ASP.NET MVC Framework Preview 2 on it.  So, am I going to try and diagnose?  Nope.  Just create another...it's beautiful.

 

 

 

 


 
Categories: Hardware | Musings | Software | Tools

March 10, 2008
@ 10:51 AM

The new Resharper seems to favor the "var" keyword and I don't understand why.  Is it some performance benefit?  To me, if you know the type, then write it as such.  Consider the following:

Person p = new Person("Tim", "Barcz");

Resharper doesn't like this and suggests the following:

var p = new Person("Tim", "Barcz");

Why?  Just because you can do something, I don't think you should.  Maybe my brain hasn't shifted back to a var world yet, but the second snippet is less readable than the first.  To me it's a case of Don't Make Me Think.  With "var", I now have to stop and think, even for a second, what type is being returned.


 
Categories: .NET | Musings | Software

imageI've thought about writing this post several times over the past two years.  Having had regular expressions come up three times last week, I thought it time to address the lack of programmers out there who understand regular expressions.  The sheer amount of fear surrounding regular expressions and the work that goes into avoiding them is astonishing.

Last year I used to troll around the asp.net forums and quite frequently I would answer the regex questions.  One question was posted which illustrates the problem with regexes among developers.

"...and i also i need to add a validator for the password textbox where the user is required to fill atleast [sic] 6 characters"

I suggested a solution to the problem using a regular expression validator. Making sure there are at least 6 characters, is a simple regex (example: \w{6,}), and yet my solution was met with skepticism.  The following was said, in the event a change was requested,

"Putting a new version of a web site can take a surprising amount of time than can go into man-weeks". 

Man-weeks?!?!?  To change a regular expression?!?!?  I see two problems, first the original developer who didn't know that regex would easily solve their problem.  The second problem is the other developer who doesn't know regex advocating his way as "the way", in effect, spreading his ignorance.  The first developer is easily forgiven, the second is not.

It's been said programmers can't program when faced with a simple FizzBuzz test, Imran states:

"Want to know something scary? - the majority of comp sci graduates can’t. I’ve also seen self-proclaimed senior programmers take more than 10-15 minutes to write a solution."

I'll pile on.  You want to know something scary?  The majority of professional programmers can't write regular expressions, even simple ones.  I'm not the first to say this.  Last year, at the ALT.NET conference, Scott Guthrie made the following statement when talking about routes in the new MVC framework:

"It's pluggable, so you can use Regexes...<some incoherent stuff>...if you wanna use regexes you can.  What we found is, regexes are super powerful, but only about 10% of people actually understand 'em."

Are regular expressions easy to understand? Well, let me ask you, was HTML easy when you started?  Were you born understanding the following HTML?

<fieldset class="CheckRadio">
    <div id="OngoingEventContainer">
        <input type="checkbox" id="OngoingEvent" name="OngoingEvent" value="1" />
        <label for="OngoingEvent">
            This is an ongoing event (no dates and times)
        </label>
    </div>
</fieldset>

If you understand the above, you didn't always.  My guess is that at some point you buckled down and learned HTML because you're job requires it.  Well, if you're a programmer, web or windows, you need to know regular expressions, your job requires it, it's that simple. 

imageRegular expressions have been around so long that they're deeply ingrained in many of the tools we use.  Christopher Bennage illustrates how regular expressions solved a recent problems in Visual Studio.  In a recent post he posts:

"Then I realized that I was missing the simple solution. Ctrl+F and a regular expression!"

I don't know that many people would be able to come to the conclusion that Christoper did.  It's my belief that regular expressions are fundamental, yet the average developer doesn't treat them as such.  They're ultimately doing themselves a disservice.

Regular Expressions are a tool that should be in every programmers bag.  If you don't understand regular expressions and do a google search every time you need a regular expression, shame on you!  It's time to bite the bullet and learn regular expressions.


 
Categories: .NET | Musings | Software

"TopicProvider.cs," the developer shouted, indicating someone in the room had committed an updated project file, but not the new file.  Humbled, I quickly went to my sandbox and added and committed the file.

"TopicProviderTests.cs," came another shout.  Again quickly I added the file.

Feeling embarrassed that I missed committing two files, I noticed that I had no icon overlays on my files, indicating my status with the CVS repository.  No matter what I did I couldn't get the overlays to come back, and boy I was missing them.  You don't realize how often you use the visual cues they provide until they're gone!

I tried:

None of the above worked.  The only thing I could think of was that I had recently installed Office 2007, which installed a folder synching program called "Groove".  I thought maybe Groove worked similarly to CVS and provided some icon overlay to notify you of a change.

Some digging provided the following provided the following from the TortoiseCVS Page:

The number of overlays allowed by Windows is limited to 15 in total. Windows itself uses 4 of those, leaving the remaining 11 to be used by other applications. If you have other software installed that uses icon overlays, the limit may be exceeded, causing some overlays not to be shown.

To resolve this problem, either uninstall the other software altogether, or manually remove one of the other icon overlay handlers. This can be done by editing the registry. Use at your own risk! You can delete [unused] entries at HKLM/SOFTWARE/Microsoft/Windows/CurrentVersion/Explorer/ShellIconOverlayIdentifiers.

A quick check of the registry key above showed the following:

RegistryWithGroove

Notice the number of Groove icons.  Windows sorts the registry based on Alpha, and this must've been found somewhere else, because if you look, TortoiseSVN stores it's overlays by preceeding the name with an integer.  Very smart!!

My TortoiseCVS overlays disappeared when I had installed Groove due to the limitation that Windows has on overlays.  I uninstalled Groove and there appeared my TortoiseCVS overlays.  Here's my registry after:

RegistryWithoutGroove 

Completely evolutionary thinking that prompted someone in the SVN camp to notice this problem and figure they should make themselves first in the registry all the time and therefore never have users experience what I did.


 
Categories: Software | Tools

January 11, 2008
@ 02:21 AM

A few days ago I posted about our frustrations with LINQ to SQL and that it was not impressing me.  After a few days and far too much time devoted to figuring this framework out, we've abandoned our attempts to use LINQ right now.  It was far too difficult to manage entity objects with it and relations, in fact we experienced the same frustration attaching our entities to LINQ to SQL as Rick Strahl, where he aptly renamed LINQ to CLUNQ:

CLUNQ

The more I look at LINQ the more I'm coming to the conclusion that using LINQ in a middle tier - especially in a generic business object architecture - is not going to work well. There are many little problem issues that when all added up point at more problems being created than solved by the entity generation and easy CRUD layer.

Hopefully I'm just being dense and there are some workarounds for some of these issues, but reading a number of other posts on this 'detached' issue at least it doesn't appear so... Apparently even the ADO.NET Entity framework doesn't address this issue. <shrug>

 

Well...back to your regularly scheduled DAL.


 
Categories: ORM | Software

Over the past year or two I've really tried to improve coding abilities by thinking on objects.  By talking about, and programming, real-world objects you can reduce the impedance with clients when discussing the problem.  I'm not alone, Karl Seguin comments about domain objects in a recent blog series about the foundations of programming:

Anyone who's gone through the above knows that learning a new business is the most complicated part of any programming job. For that reason, there are real benefits to making our code resemble, as much as possible, the domain. Essentially what I'm talking about is communication. If your users are talking about Strategic Outcomes, which a month ago meant nothing to you, and your code talks about StrategicOutcome then some of the ambiguity and much of the potential misinterpretation is cleaned up. Many people, myself included, believe that a good place to start is with key noun-words that your business experts and users use.

While looking at LINQ over the last few days I've become disappointed to find out that many-to-many relationships aren't supported.  Sure you can hack you're way around it, but anyone can hack their way around anything.  If you question whether or not it's a hack, consider all the language features implemented to make LINQ work and still many-to-many isn't supported.

LINQ requires an intermediate class in order to do a join.  In the real world there is no such this as OrderProductJoin or TopicCategoryJoin, so why do I have to have that object in code?  That smells funny.

I feel the pain of Hamilton Verissimo, the founder of CastleProject, when he comments about FUD surrounding Castle.  ActiveRecord, as an ORM, has respected the domain object for quite some time while providing Many-to-Many support.  LINQ however requires an DBML file, the usage of DataContext everywhere, and doesn't support many-to-many joins.

David Hayden, respected blogger and Microsoft MVP defends LINQ to SQL but adds:

DLinq is perfect for those developers who focus on small applications and Microsoft-related technologies.

After having used both NHibernate/ActiveRecord and LINQ, the clear winner right now in my mind is NHibernate/ActiveRecord, despite LINQ having the backing of Microsoft.  ActiveRecord respects the domain model allowing you to talk about objects with a shallower learning that LINQ.


 
Categories: Musings | ORM | Software

Scott Hanselmen posted this morning about aideRSS.  I decided to run aideRSS over my blog to see what would the results would be.  Apparently I have only one "Great Post" which made me chuckle:

aideRSS

Apparently my test post from yesterday was "Great".  I wonder if that's an indictment on all my other posts or something internally goofy with aideRSS's calculations.  I was impressed that AideRSS correctly labeled my Vista Printer Installed - Dell All-In-One 922 Now Printing and Nant Setup for Visual Studio 2008 and .net 3.5 as having the high scores in the PostRank column.  These two posts are clearly the most trafficked when I look at site statistics.

I have to say I'm impressed with what how it works:

"...in a nutshell you enter the URL of the feed that you would like to have filtered and we do some math and checking around the web to learn about this feed, its statistics, and people’s reaction to it. We then assign PostRank™ scores to all articles in the feed and provide you with a variety of tools to sort and parse these items of interest into manageable lots for you to scan and digest at your leisure."

Scott's explanation may be more meaty:

"Well, since it can't really measure quality it infers it indirectly by creating a metric based on the number of del.icio.us bookmarks, diggs, Blogger references, Technorati references, Google BlogSearch reference, IceRocket references and a few others."

As I'm blogging more I intend to check in on AideRSS every so often as I think this is just another way to see which posts are worthwhile and which aren't.  However, I will say that it briefly crossed my mind to retire from blogging seeing as how 100% of my posts are "Good", easily beating two of my favorite bloggers Scott Hanselman (61%) and Jeff Atwood (75%).


 
Categories: Musings | Software

I've had it happen a few times since starting to use Live Writer a few weeks ago.  I'll post and see the new post and then the post will be gone.  The latest occurrence is this morning's post about Linux.

I presume it to be a Live Writer problem since I never had this problem when using the HTML Wysiwyg editor in the dasBlog.  However the strange thing is that the post is clearly visible, which means it's gotten to dasBlog just fine only later to disappear, so is this a dasBlog problem?

Anyone have any idea what's going on?


 
Categories: Software

December 15, 2007
@ 01:24 PM

I'm reacquainting myself with Visual Basic.  However at this point I'm seeing some strange behavior.  I'll quickly navigate around it but I just find it odd, take a look for yourself:

Vb Exception Oddities

What seems very strange to me is that you can see very clearly that on line 1041, System.FormatException is being caught, however the exception is never caught.

I'm wondering if it has to due with the multiple statements all in one line?  Any thoughts?


 
Categories: Software

December 13, 2007
@ 06:08 PM

Has this ever happened to you?  You been asked to put together something quickly to demonstrate some functionality and it somehow has ended up in production?  I have, and for that reason, I believe there is no such thing as a prototype.

When I'm asked to see if something is possible, I, being a good pragmatic programmer, run off to implement a quick prototype.  Author David Thomas explains the idea of a prototype:

Prototypes by their nature are not designed to be long lasting code. Prototypes are designed to be thrown away. They're one-offs. It is inappropriate to over-engineer a prototype. A prototype is like a town in a western movie. It's all facade. There's nothing behind it. You cannot move in and raise a family in one of those houses.

If you've been around for any period of time in development, you've probably written something yourself, or at the very least seen something that has weaseled it's way to production that was never meant for production.

Believe it or not, the site below is in production. 

proto2

Currently the site performs limited, but somewhat crucial, functionality.  The administrative home page clearly leaves something to be desired.  However, I happen to know the developer who worked on this site and he explains that it was never intended to go live in it's current state.  Business rules/needs trump gold-plating, it's a concept that the business-brain part of me understand, but the developer/craftman.

Talking with another developer today, he recalled a system he put together as a consultant to demonstrate some piece of functionality.  Some time later another developer was putting a pretty UI on it, since it had made it's way to production.

I think somewhere deep inside of developers, we know that when asked to prototype something it may someday end up in production, whether we build it for production or not.  Developers are prideful, artistic creatures.  Our code is our craft!  We're also learnable.  I now tend to make prototype code something I would be proud of if I were to show it someone else.

Ultimately I think prototypes are a great tool, but there's a danger in the prototype going live, which from the definition above isn't sustainable.  Ultimately that's why I'm jaded a bit and say that a prototype is an imaginary thing, only production and soon to be production.


 
Categories: Musings | Software

Programming languages these days do their best from keeping you from doing something stupid.  We have compile time checking, "managed" code, and garbage collection.  We've been led to believe that if you just write the code, in any fashion that meets the requirements of the project, that any missteps you may take in code will be corrected. 

That's the case with garbage collection.  We've been sold this idea that variables can be created wherever, whenever, and however you want, the runtime environment will clean up after you.

However the following blog post titles (all from the same great author) tell a different story:

Last Friday I spent the day going through a windows dump file tracing down a poorly performing application's problem for a client.  With a dump file I have a snapshot of everything going on at that moment in that process (aspnet_wp.exe).  It's an interesting challenge.  Given that snapshot, it's an interesting to see what you can find out.  However, I would assert that not enough developers know how to use it, or even of it's existence.

A quick poll of 12 developers I know showed that only one had ever used WinDBG and he qualified his "yes" vote with "yes, although not very well".  Extrapolating that figure would show that  92% of developers cannot debug their application without Visual Studio support.

Do the post titles above inspire confidence in the .NET Framework?  If there was a "strange" problem occurring in your application, are confident you could fix it or identify a list of possible problems?  Could you do it while the application is running in production?

If your WinDBG skills are lacking, I encourage you to take a little dip into WinDBG and get your feet wet by following the guide from Johan Straarup

Happy debugging!


 
Categories: Software

December 5, 2007
@ 05:06 PM

Who ever thought this was a good idea?  It feels wrong on so many levels.

Dim enableRegistration As Boolean = CBool(IIf(CBool(DataBinder.Eval(e.Item.DataItem, "IsOnlineRegistration")), IIf(CInt(DataBinder.Eval(e.Item.DataItem, "EventSize")) = 0 Or CInt(DataBinder.Eval(e.Item.DataItem, "EventSize")) = -1 Or (CInt(DataBinder.Eval(e.Item.DataItem, "EventSize")) - CInt(DataBinder.Eval(e.Item.DataItem, "Registrants"))) > 0, True, False), False))

And since we code review like the mafia, put the poor soul out of his misery .


 
Categories: Software

Yesterday I posted about an issue I was having with Nant and Visual Studio 2008.  The solution I found from Jeffrey Palermo ultimately only got me so far.  First, let me say that if I simply wanted to build the code, the solution Jeffrey provided was adequate.  Where I ran into issues was when I was trying to use the "gac-install" task which is provided by the NantContrib package.  I was using this task in a "test" target, which run my unit tests.

I kept receiving an error when running the "test", which included the "gac-install" as one of it's tasks:

"The SDK for the 'net-3.5' framework is not available or not configured."

So why did Jeffrey's version work and mine not?

I dug around a bit and looked at the nightly build for nant, as I read somewhere that there was 3.5 support built into nant but just not released yet.  I looked into the nant.config.exe provided with the download and found that it does not yet work out of the box as it points any 3.5 project to use the 2.0 version of msbuild. (note to self, hop on SourceForge and make a bug or help with the fix)

Not one to give up, I dug into the nant configuration.  Inside of the nant.exe.config there are two properties from which many other properties are derived, those two properties are

  1. installRoot
  2. sdkInstallRoot

These two properties are read from the registry.  The registry entries are created when you install Visual Studio or the SDK.

They're used within the nant config file as part of other properties and attributes, for example:

sdkdirectory="${path::combine(sdkInstallRoot,'bin')}"

When using the msbuild task (again provided through NantContrib) the installRoot property is set to C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727, which is where msbuild.exe lives for the 2.0 framework.  However registering something in the gac uses gacutil, which isn't located in the same place as the framework.  gacutil.exe is located (on my machine) at C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin.

How does this all relate to nant and 3.5?  Well the installRoot property is used by msbuild.exe, which in Jeffrey's example, was being set correctly, which resulted in the proper execution of my nant "compile" target.  My unit test target, which uses the "gac-install" task, relies on the sdkInstallRoot property.  In Jeffrey's example his config had the following element within the xml blurb he posted:

<readregistry property="sdkInstallRoot" key="SOFTWARE\Microsoft\.NETFramework\sdkInstallRootv2.0" hive="LocalMachine" failonerror="false" />

The problem, at least on my machine, is that I don't have that registry key!  I was able to get everything working simply by changing what key it was pointing to.  I ended up with the following (bolded text indicates what has changed):

<readregistry property="sdkInstallRoot" key="SOFTWARE\Microsoft\Microsoft SDKs\v6.0A\WinSDKNetFxTools\InstallationFolder" hive="LocalMachine" failonerror="false" />

After that change, everything is working properly.

Thanks to Jeff for his original post.  It may not matter but I'm going to post my PC specs anyway, since the paths mentioned above may be OS dependent.  I'm currently running Windows XP SP2 with only VS 2008 installed on it.


 
Categories: Nant | Software

office_space_baseball.jpgI'm exploring the new HealthVault beta from Microsoft.  Every document on the MSDN site regarding HealthVault is downloadable as an .xps file.  In my attempt to print a document, I've read numerous blogs posts this morning about how XPS (Xml Paper Specification) is supposed to be superior to PDF but I would strongly disagree.  Here's my experience trying to simply print a .xps document (which hopefully you won't experience):

  • Click on download link (using Firefox), I'm then asked if I'd like to open the .xps document with "XPS Viewer" to which I say yes, only to find that another tab is opened in FireFox asking me the question again.  Another affirmative answer opens another blank tab asking the question again, you can see where this is going.
  • I'm smart, so I'll save the .xps document to my desktop and open in IE.  Sure enough, the file opens and I can read it fine.  I go to print however and I only have 3 printers to choose from, none of which are my actual printers (you know the things that spit out paper and have cryptic messages like "PC Load Letter" .  Normally I have nine printers, but now I have three, so I start seeing what I can do with these:
    • Microsoft Office Document Image Writer - This "printer" is there but selecting it disables the print button.
    • Microsoft XPS Document Writer - This "printer" asks me where I want to save my file...as another .xps document.
    • PrimoPDF - When choosing to "print" to a pdf file I encounter an error.
  • Now I'm at the point where I'm googling for a solution.  I can't find squat, maybe this problem is limited to me.  I do find a pack to download the viewer on Microsoft's site, so I try to download a viewer, hoping that the problems I have may be fixed in a new version.  The installation comes in the .NET 3.0 redistributable, and low and behold it fails to install, saying I already have the .NET 3.0 redist.
  • So I find another option on the Microsoft XPS page for the "Microsoft XPS Essentials Pack".  Mind you there's a nice note telling me the option explored in the previous step is "recommended for your system configuration."  I download and install the "Essentials" pack with no problems.
  • Now I open the .xps file in the standalone xps viewer and am please to see that when I go to print that all of my printers are there.  So I attempt to print to the default printer and everything seemingly works...until I see that only 11 pages print of the 58 pages.  I print to a different printer, this time 19 pages.  Better...but still wildly deficient.  Next I try printing to pdf, I open the PDF and all 58 pages are there.  I print from my PDF reader and all 58 pages come out of the printer.

That's it...simple.  What I don't get is why people are so afraid to embrace new technology?

So to summarize, here is how to print a .xps file:

  1. Download the "Microsoft XPS Essentials Pack".
    1. Make sure you have the .net 3.0 redistributable.
      1. You first need the .net 2.0 and .net 1.1 before you can install the 3.0
  2. Change the default program to handle .xps documents.
  3. Print your file, selecting the "PrimoPDF" printer.
    1. Install PrimoPDF if not installed.
  4. Now open the result PDF in your reader of choice.
  5. Print your file, selecting the hardware printer of your chioce.

There it is, easy as 1...1a...1aI..2...3...3a....4....5


 
Categories: Musings | Software

I've recently finished reading Steve Krug's Don't Make Me Think which was highly recommended by both Jeff Atwood and David Sturtz, Geonetric's information architect.  One of the points the book makes is that the users of your website nowadays have been so conditioned by Google that they expect to see a search box. My contention is that adding "search" to your website is no trivial matter.

There seem to be few categories your site can fall into, here are three that I'm familiar with:

Scenario 1:

My father has a website, with a number of pages of static content.  The pages are .aspx pages only to utilize features of .NET like MasterPages and/or themes.  The content is static.  To implement a search I need to somehow index the content, which should be easy, in theory since the content is static.

Scenario 2:

I've built a small CMS system for myself, to manage pages and content.  The pages are dynamic in that when you request a page, no page exists on disk and is loaded from a database.

Scenario 3:

A large CMS with multiple different "objects".  You may at various points want to search for specific "objects" or search across all "objects".  I'm thinking back to my last job where we had a large site to manage baseball tournaments.  There were three primary "objects", players, teams, tournaments.  There was a general search that had to search everything and individual searches for each object that would only return those objects.  In other words the site wide search for "Blue Devils" would return both the "Cleveland Blue Devils" team as well as the "Duke Blue Devils Classic" tournament.  The same search in the team and tournament section would only return the team and the tournament, respectively.

Options:

  • I could use Google to search my site.  You've seen the "search this site" boxes on websites.
    • Pros
      • Google indexes well
      • Easy?
    • Cons
      • lose the "look" of your site since you're using google for the search results page.
      • Can't index "objects".  Google can index only public facing web pages/documents.  Therefore (using Scenario 3) a tournament could only be found if the name appear prominently somewhere where Google will find it.  In other words you're relying on Google, a lot.
      • Cannot limit Google to certain "objects".  I can't say, "search only pages that are about Teams", where I could do that quite easily implementing my own search
  • Implement my own search
    • Pro
      • The algorithm is my own and I can change it if I'd like.
      • Keep "look" of site by never leaving site.
    • Cons
      • Much more work.  Writing my own SQL to search and aggregate the results.  Do I full-text index on tables?  Do I use a third party solution?

It's a very tricky proposition.  Krug says that users will look for a search box, so that means you should put one there right?  If you put a search box on your site that doesn't produce reasonably good results then the user will lose faith in your website and may leave.  If you don't provide a way to search your pages/data, of which there may be quite a bit, then the user may struggle to find what they're looking for and leave.  The only option you seemingly have is too implement search and implement it well.


 
Categories: Musings | Software

As a developer I want to build something neat, that impresses others and makes someone's life a bit easier.  This most commonly manifests itself in a problem that could be easily solved but I've added various extensibility points that were neither required nor will probably ever used.  In times where I find myself slipping into one of those modes, where I'm just adding functionality for the sake of functionality, I remind myself of YAGNI ("You aren't going to need it") who's main tenet is:

Programmers should not add functionality until it is necessary

I was reminded of this twice recently, the first last Saturday, the latest being tonight. 

Last Saturday I was talking with family while at a parade.  The discussion of brainstorming came up.  The somewhat well-known story, or so I'm told, was reiterated to me on Saturday.  It has to do with a power company trying to figure out how to remove ice from electical lines.  When the ice would build up the lines were in danger of breaking under the weight of the ice.  Here's what they came up with during a brainstorming session on how to fix it:

"during one of the breaks, one of the linesmen shared with some of the participants about how came face to face with a big, brown bear when he was servicing the power lines, and how he narrowly escaped being mawed by it.

when they returned for the meeting, someone suggested training the brown bears to climb the poles to shake off the ice from the wires. brown bears were very common in the areas that they were looking at and they are strong enough to cause the poles to shake when they climb the poles.

someone else then suggested putting honey pots at the top of the poles to entice the bears to climb the poles.

they then started to discuss about how to put the pots of honey at the top of the poles and someone threw out the idea of using helicopters to do the job."

The idea however was quickly abandoned for a more simpler solution when a secretary pointed out the following:

"a secretary in the meeting pointed out that the down wash from the helicopters could possibly break the ice and blow it off the wires."

The helicopter idea works, and is still in use to this day (read the whole story), but how cool would it be to sit back and say, "I trained some bears to climb a tree in search of honey to solve our problem."  The story is typically used to illustrate how even crazy ideas in brainstorming sometimes aid in finding a simple solution.  As a programmer however, I learn from the story the fact that they implemented the helicopter solution because it was easy, safe, cost-effective, and quick to implement.

The second, and latest, reminder occurred tonight when talking to a co-worker at a client cocktail party. The co-worker was talking to me about a conversation with a client who's main complaint is that we have to provide everything "whiz bang".  Typically "whiz bang" denotes something cool or neat, however, the gripe was not that what we delivered was bad or wrong, but that in our pursuit to "wow", we didn't "wow" the client because it took a long time to implement.

Over-architecting.  This is a seemingly common trait in developers.  If you work on a team it's likely that you're constantly having to fight this from somewhere within the team.  On days where I'm dutifully adhering to the YAGNI principle and building shippable software, someone else on my team may be in the throes of a battle of over architecting.  Likewise while everyone is adding real features, I may be dreaming and scheming of ways to make a program über-great.

I have to keep reminding myself that shipping software is the most important aspect of a software company.  It seems too simple to carry any real weight; like something as simple as a shippable product is enough.  It's really a novel idea considering how much software I've shipped recently.


 
Categories: Musings | Software

Today I passed my first Microsoft Certification test in about seven years.  I passed the first of two tests, 70-528 (Microsoft .NET Framework 2.0 - Web-Based Client Development) on my way to MCTS.  I've had mixed feelings on certifications and still do to this day.  I know some very talented certified developers who add to the MC* reputation.  Likewise I know several developers who despite being certified, can't program, and weaken/cheapen the MC* title.

My reaction to the test is that it is heavily weighted in places that seemingly don't matter "in the real world".  I'm keenly aware I could be way off base here, however I've been working with .NET now since 2003 and asp before that.  The two areas that were heavily stressed in my test were deployment ("Copy Website", Publishing, aspnet_compiler) and Mobile Controls.  In my nearly 5 years with .NET I have never written an application that uses mobile web controls.  Should I have? Am I strange?  Regarding "deployment", at Geonetric, we have a build server which uses Cruise Control and NANT, and therefore I rarely (read:never) have used the "Copy Website" function from within Visual Studio to get a site to a staging server, nor used the "ASP.NET Configuration" application to change web.config settings in my production machine.

While the debate can rage on about the relevancy of tests, I'm softening my position on them and do see them as beneficial (maybe for another post) when taken as part of a whole.  In some chats with Scott Hanselman about the subject recently, he took the stance that certifications are just a good resume line item but the most important thing was to ship software, not what collection of consonants you can string together behind your name.



 
Categories: Software

August 8, 2007
@ 09:20 PM
We recently hired a DBA here at Geonetric to fill a much needed niche.  While we have several better than average developers in terms of SQL, I'm excited to see what very SQL specific optimizations (ie indexes, normalization, filegroups) that Jason (DBA) can bring to the table.  Thinking about the optimizations that will be handled at the database level, I stopped to think of the "stack" to deliver a web application.  Here's my first-pass list:
  • HTML
  • Javascript
  • CSS
  • Presentational Logic
  • Business Logic
  • Data Acess Logic
  • Data Access
Looking at the list above.  Optimizing a single layer in no way gets you great performance across the entire application, however a poorly built/optimized layer can ruin the entire application.  What's the saying?  A bad apple spoils the bunch?

We can optimize to make all queries fast and performant but negate that optimization by serving up CSS in a style block (rather than externalizing into a CSS file).  We can use Ajax to avoid fullpage postback, but if backed by a slow web method the performance gain sought by using Ajax is nullified. The point is that if performance is a goal you have to pay attention to the whole stack.  Paying attention to just one piece while disregarding the others will ultimately not produce the performance you desire.


 
Categories: Musings | Software

August 3, 2007
@ 03:13 PM
Sopranos.jpgWe're a growing software development company.  As we're growing in numbers we're finding that we have to implement a more formal process for code reviews.  In the past we could just look over each other's shoulders and give a nod.  It's just not feasible to do that anymore given the growth we've had. 

The code review process can be tricky in that you have to be clear with everyone going in that a review of code is simply in the best interest of the company and that anything said shouldn't be said or taken personally.  Being one who places a lot of pride in my work, I fight the urge to defend my code/design.  I'm trying to live by the following summation of how to code review:

"Code Review like the Mafia"

In the television drama The Sopranos there are frequent arguments between characters.  No matter how much arguing, fighting, or threats, the characters almost always are friends right after.  Business is business, nothing that is said during an argument sticks or lasts too long.

Maybe it's a bit utopian to think that we could code review like that, not having to fear/worry about people's feelings during the review and knowing that no matter what was said we could go grab lunch together afterwards.  Again, pointing the finger squarely at myself, is it reasonable to be pummeled in a meeting about your work and not take it personally or get worked up?  For me that's a tough one that I'm going to have to work on, I mean let's face it, I'm not part of the mafia.

 
Categories: Musings | Software

The Model View Controller pattern (MVC) seems to be the pattern du jour in many development shops.  That is until of course, some literate nerd reminds everyone, that there is "No Silver Bullet."  The recent rush to Ruby on Rails, which implement this pattern out of the box, has only served to add to the number of people singing the praise of MVC.  Microsoft marketing fed programmers seemed to be quick to retort that the WebForm in Asp.NET is in fact an MVC implementation.  I can't speak for others, but "the codebehind is the controller" always felt a bit like kissing your sister.

The other day I started playing with MonoRail, Castle's MVC implementation for the .NET framework.

"MonoRail differs from the standard WebForms way of development as it enforces separation of concerns; controllers just handle application flow, models represent the data, and the view is just concerned about presentation logic. Consequently, you write less code and end up with a more maintainable application."

My first reaction after overcoming the newness and understanding the project/solution layout was that this felt like how it should be.  I was programming a class and that class held nothing more than data about the object.  My controller for that "model" was shuffling things around and making the decision about what to do and when.

There are obviously some things you give up when going to MonoRail but I hope to assuage your fears and mine by digging in a little further.  Here are the items I have on my notepad to learn:

  • Are base class library tools (TextBox, CheckBoxList, ect) as well as third party tools (ie. Component Art or Telerik) no longer available?  If they're no longer available are the counterpart offerings as good as what is offered using WebForms?
  • Ajax?  Seemingly ASP.NET Ajax is out if you go with MonoRail, so what to use instead?  Has MonoRail adopted one of the javascript libraries as it's main provider for javascripting/ajax?  If so how does it compare in ease of use when compared to ASP.NET Ajax?
  • Af first glance, there also no longer seems to be ways to use server controls or user controls?  Is this statement accurrate?  If so what is the proposed method of getting the same functionality.

The MonoRail/Castle team has done an incredible job in my mind at making this a viable option instead of WebForms.   I still have a lot of reservations about the end-to-end usage, but I've let down my guard immensely after getting my feet wet.  Judging from the user base out there by viewing blog posts and/or forums about MonoRail there's enough of a following that I'm fairly certain the issues above are solved.  If they are in fact solved, then I have great confidence that they'll be just as easy and "right" to use as MonoRail, which will make MonoRail hard to ignore for future projects.


 
Categories: Musings | Software

July 21, 2007
@ 11:21 PM

Bored!Occasionally I interview prospective employees at the company I work for.  In the course of the interview I of course look for technical competency, but I also look for passion.  Passion in my mind is the opposite of boredom.  I think 9 times out of 10 I'd take a passionate programmer instead of the bored all-star.  Why?  I think passion for the technology you're working with will ultimately be visible in the product you're developing.  Passion can manifest itself in different ways, so don't look for it always in the same place.  Geonetric in many ways has done an excellent job in hiring passionate employees.  I want to give you two recent examples, but some of my co-workers read this so I'll keep the following as minimal as possible. 

  • We have one developer who was in the break/lunch room with me and we got to talking about a problem.  The discussion got to the point where we needed to go look at a computer screen, the discussion went something like this:

Me: Yada Yada Yada....I'll show you later after you eat.

Developer: Let's go look now.

Me: Now?

Developer: Yes, learn first.

"Learn first."  That's passion.

  • Another developer, fresh out of college, has jumped right in to the project to the point where I don't look at him at all like a fresh college grad anymore.  His passion is a project on the side where he's seeing if he can better deliver web content using XSLT and XML rather than delivering (x)html (sorry Scott if I've butchered the goal).  Is it relevant to what we do daily at work? Maybe.  Maybe not.  The point is that he is passionate about XSLT/XML and jiggering with the technology to bend it to do what he wants.  That's the kind of guy I want on my team.

Passion in my mind is a key characteristic of being a great developer.  A passionate developer is will never stop learning and enjoys the journey of learning and thus is an asset to any team.


 
Categories: Musings | Software

An analogy: A person does not pack the same for a overnight trip the same things as they would for a month long trip.  The month long trip requires not only more luggage but also has to take into account things that wouldn't need to be accounted for on an overnight trip.  In other words, you have to pack adequately for the trip you are going on.  The luggage you'd take on a month long trip is too much for an overnight and the same is true for a single overnight bag taken on a month long trip.

In software terms I'm finding myself to be like the guy who too has taken many weekend or short vacations packing only a single pair of underwear and a toothbrush and thinking the same will be adequate for a weeklong cruise to Alaska.  It's not.  What works in a smaller environment and brings success there does not inherently bring success on a larger scale.  In keeping with the analogy, I can't say to the Maître de on the cruise, "My bathing suit is surely adequate for this formal dinner, I've worn this bathing suit hundreds of time before."  The analogy is silly, but the point is that what works in one situation doesn't work elsewhere.  Where a bathing suit is adequate for a weekend camping trip it's not for a cruise.  On that cruise there are expectation of other passengers and the dining room that you will dress appropriately.

In terms of software that means planning better, capturing requirements better, understanding the business behind the decisions, keeping fellow developers excited and passionate about what they're working on, dealing with interpersonal communication better, and making sure that everyone is on the same page and that we're all working toward a common unified target.  As we grow, I need to perform better in these areas.  It's not something I can put off and figure out later.  If I/we don't plan properly and "pack correctly" there may not be a later.

So wherever you are and whatever software project you may be working on ask yourself what the goal or aim of that software is and if you've packed properly for it.  Because if you haven't, you may not get a seat at the table.

 


 
Categories: Musings | Software

I've known about Flickr for some time.  It's touted as a great Web 2.0 site with all the Ajax trimmings.  I tinker and sign up for websites all the time with no other purpose than to just try it out.  I never did so with Flickr.  Whether it was because I don't take that many pictures, Picasa seemed to do the same thing, or the fact that my snapshots seemed outclassed by some of the photos already I don't know.

There's also some pretty neat research stuff going on with Flickr and tagging, the coolest I've heard of lately is PhotoSynth from Microsoft (check out the neat video from the TED Conference).

I signed up for an account and uploaded pictures after wanting to upload some pictures of my new son Lincoln.  The computer I was on was a "rental" from the hospital and was severly limiting.  I used Flickr to upload and resize the pictures automatically.

Geoffrey A. Moore wrote in his book Crossing the Chasm (Google Book) regarding technology

  • the first 2.5% of the adopters are the "innovators"thechasm.jpg

  • the next 13.5% of the adopters are the "early adopters"

  • the next 34% of the adopters are the "early majority"

  • the next 34% of the adopters are the "late majority"

  • the last 16% of the adopters are the "laggards"

When it comes to photos I'm clearly in the "Customers want solutions and convenience" group.  Now that I've found Flickr, I think I'm on Flickr to stay.  It's free, it's Yahoo owned and therefore very reliable and very responsive.  The Ajaxy goodness is nice and very cool, but the Ajax is really just a means to an end.  The actual things I want to do with my photos once uploaded have already been thought of and are provided through a quick, reactive drop down.  Very slick Flickr! Thumbs up to you guys and thanks for helping me out of a bind.
 


 
Categories: Software | Musings