Wednesday, May 28, 2008

ALT.NET Geek Dinner Recap

The pizza was good and the conversation was even better.  We had 9 people show up and we talked a lot about tech, Microsoft, Test Driven Development, and beer!

I brought up the subject of possibly organizing an ALT.NET Open Spaces conference here in Houston, and folks seemed interested.  I'm a little frightened by the amount of work this will be, but in the end I think it will be worth it.  We also decided on getting a google group setup, so if you're in the Houston area (or just want to listen in) then join us at http://groups.google.com/group/houstonaltdotnet.  We'll use this for future planning.

Unfortunately I forgot to take a picture of the group, whoops!  I guess that just means we'll have to meet again :)

Tuesday, May 27, 2008

Using ASP.NET MVC on IIS 6 without the .MVC Extension

One awesome features of ASP.NET MVC is the clean URLs.  If you aren't familiar with them, here is a sample:

/products/list

(versus a typical /ProductList.aspx)

The default route for ASP.NET MVC looks like this:

/{controller}/{action}

Using this route you can map most of the URLs that your application will need.  There is a problem, however, when running ASP.NET MVC on IIS6 (and 5).  The URL above doesn't have an extension, so IIS will assume that it is a virtual directory on the server.  We have a couple of options we can do to get around this:

  • We could create wild card mappings and pass every request through ASP.NET, however this is not recommended for performance reasons
  • We can add an extension that maps to ASP.NET (.mvc)

In the latter option your routes must change to something like this:

/{controller}.mvc/{action}

So URLs generated with this route will look like:

/products.mvc/list

...which basically reverts our clean urls into, well... less clean ones.

So if you want to deploy to Windows Server 2003 & IIS 6, you're out of luck.  Well, mostly...

URL Rewriting to the Rescue

We can leverage an ISAPI filter to rewrite URLs which will allow us to have the nice URLs while still on IIS 6.  There are 2 major products that do this for IIS:

ISAPI Rewrite is the more mature of the two, however it's not free.  They do provide a free version, but it doesn't support regular expressions, so it's pretty useless.

Jeff Atwood has a nice write-up of these two utilities.  In it he notes that the syntax for Ionic's ISAPI Rewrite is a little stranger and doesn't support the regex that we're all used to (since it uses a C regex library, not a .NET one).

I decided to choose Ionic's because it was free, however there was a lack of information on how to structure URLs, and it required a lot of trial and error to get it working.  Luckily they have an automatic logging facility that tells you how the rules are matching up.

For ASP.NET MVC, I needed to cover these cases:

  • A request for / should be redirected to /home
    This isn't really required, as .NET can do this for me, however I wanted to ensure that all entry points are at the same URL to avoid Page Rank issues.  (See the same Atwood post for information on how important this is)
  • A request for /something should be rewritten to /something.mvc
    That is, the user will request it without an extension, but the filter will rewrite it without the user's address bar ever changing.
  • A request for /something/index should be rewritten to /something.mvc/index
    Just making sure that URLs with actions get the extension only on the first part
  • The content directory that contains our javascript, CSS, and images should be excluded from the above rule
    Otherwise we'd have /content.mvc/styles.css which would be interpreted as a controller, rather than a direct file request.

I found a good resource that outlined how to do this with ISAPI Rewrite, however the rules were quite different with Ionic's.

Here are my rules for Ionic's ISAPI Rewrite that works for ASP.NET MVC:

# empty URL gets mapped to home controller 
RewriteRule  ^/$                 /home [R] # map controller parts of urls to .mvc, ignoring the content directory
RewriteRule  ^(?!/Content)(/[A-Za-z0-9_-]+)(/.*)?$          $1.mvc$2  [I]

It turns out that I only need 2 rules to satisfy the above requirements.  The first rule forces the browser to redirect, which will aid in making sure that I only have 1 entry point to my website.

The 2nd rule takes the first part of the ULR and adds .mvc to it, appending the remaining verbatim (if any).  It also excludes anything beginning with "content," so I'm free to put images, javascript, css, and other literal file resources there.

The last requirement is to define my routes with both .mvc and regular formats.  The trick is to define them in the right order.

routes.MapRoute("basic", "{controller}/{action}", new { ... } );

routes.MapRoute("basic_mvc", "{controller}.mvc/{action}", new {...});

Doing this ensures that our .MVC routes will actually function, but when we ask the framework for a URL (such as with Url.Action() or Html.ActionLink) we are handed the extension-less route (since it is defined first).

Route Testing is IMPORTANT

I've said it before and I'll say it again.  Route testing is important.  A single tiny change can break an entire application.  Applying automated tests is critical for any MVC application.  Since deployment of an ASP.NET MVC application needs to be flexible, your application should function with either type of route (extensions or not) so that you have flexibility of deployment.

Hard coding a route in 1 single location will prevent you from doing this.  Did I mention route testing is important?

Wednesday, May 21, 2008

Houston ALT.NET Geek Dinner - Next Tuesday

If you're in or near Houston, then perhaps you can join our first ALT.NET gathering, which will be an informal geek-dinner!  We will discuss various concepts around ALT.NET and see if we can get the ball rolling for organizing an open-spaces conference sometime this year.

When: 5/27/2008 @ 7:00 PM  (That's next Tuesday)
Where:

Star Pizza
2111 Norfolk
Houston, TX 77098

(google map)

We're not really sure how many are going to attend, so please leave a comment if you plan on joining us.  I'd like to notify the restaurant if we're expecting more than 20 to show up.

Hope to see you there!

Sunday, May 18, 2008

Austin Code Camp Rocked! (And I'm Tired)

Austin Code Camp 08 was a success, and I’m really glad I participated in it.  About 150–200 eager developers came to learn and network with others from around the area.

I was able to attend 2 sessions, the first was “Agile in the Enterprise” by Joe Ocampo.  His talk was full of a ton of powerpoint slides which really didn’t fit in with the size of the talk.  Here are a few highlights:

  • What makes success?  -> People, Communication
  • What makes failure? -> People, Communication
  • People are often overlooked as critical factors of success of any project.
  • “The worst thing you can do is isolate architects from developers.”  — I couldn’t agree more. 
  • Siloed teams lead to lack of communication, trust.  Change is very difficult.
  • Composite teams are cross-functional – based on component, feature, subsystem, interface
  • Agile projects will generally cost MORE — I can’t say I fully agree with this
  • However, ROI can be realized much sooner, which can help overcome that cost
  • In a waterfall project, technical debt is incurred and generally not paid back.  Leads to lower pace and more costly maintencance.
  • In an agile project, technical debt is minimized, keeping a sustainable pace and enabling change without high cost
  • “Innovation Games” — to help you drive out features/priority with your customer

Some pics:

Iphone 032

Iphone 033

Next I went to a talk entitled “Designing for Stupid Users” which was a fantastic title.  The talk was about User Experience Design and I found it to be informative but a bit dry.  The speaker obviously knew the topic well and could speak to it, but the power point slides where just loaded with text.

There was a great picture on his deck though:

Iphone 036

Basically (it’s hard to read) it says the left most “thing” that the users interact with is the screen.  They then go through many different layers of “stuff” to get to their overall goal, which is a business action.

The rest of the day was me speaking, and I think they all went very well.  I did notice, however, that the DDD with NHibernate is just too much material to fit into an hour.  I should have submitted these as 2 sessions.  I also ran out of time in the Advanced CSS & Javascript talk and didn’t get to demo much javascript.

All in all, it was a great event, I got to meet a lot of very cool people and I learned a bunch as well.

Thanks to all who organized, spoke, or attended the event!  It was awesome.

To end the evening, we went to have beers at a nice place.  Scott Bellware showed up and we had some really good conversations about community.

Iphone 038

Iphone 039

And then I made my journey back to Houston and slept for 10 hours. 

(oh, and you can download all of the material from the code camp at their google code repository)

 

Tuesday, May 13, 2008

Screencast - Test Driving an Inventory Screen

A few weeks back Chad Myers and I recorded a screencast to demonstrate TDD in action.  We had some issues with the recording (again) but I was able to mix it all up and produce this stellar TDD screencast for all of you friends.

A couple things to note:

  • Chad and I are BDD enthusiasts, not experts... so you might see a bit of a quirky hybrid approach.  Don't TwitterFlame us please ;).  I am, however, finding that the more and more I use BDD style tests that I feel myself leaning towards that style, but it's a progression.
  • Chad and I apparently live in different time dimensions, as our audio streams were totally out of sync.  I tried to fix it, but I'm a coder, not a production contortionist.  It's definitely watchable, but the last 20 minutes or so is a bit off sync.
  • It's long...  I tried to bring it down a bit by cutting out silence, but then I just wanted to release it already :)

So without further ado, you can watch the screencast here:

http://www.benscheirman.com/screencasts/tdd-inventory

Total Length: 94min

Please let us know what you think in the comments.   If you find this is useful then perhaps we will do more of these.

update:  a few of you have asked for the code.  I’ll be sure and make this available for future screencasts.  You can download the project here:

File Attachment: TDDInventory.zip (139 KB)

Speaking at Austin Code Camp this Saturday

I must be crazy.  I submitted four sessions for Austin Code Camp and they were all accepted!  It will be a long weekend for sure.  You can find out more details here:  http://www.austincodecamp.com.

If you're going to attend, be sure to hit up one of my talks:

  • ReSharper-Fu
  • Inversion of Control Quickstart
  • Advanced CSS and Javascript
  • Domain Driven Design w/ NHibernate

I'm sure that we'll put together some sort of geek dinner to unwind afterwards.  If you're interested, drop me a line in the comments!

Saturday, May 10, 2008

Cage Match: Gantt Charts vs. Burndowns

A large majority of the projects that I come into contact with start out with some sort of Gantt Chart.  Whether it comes in the form of Microsoft Project or just Excel, this is something that is very common in the software development industry.

A typical project plan looks like this:

project-plan

There's a list of tasks on the left, which are things like "Create Component X" or "Build Customer Search Screen."  The next column shows the estimated duration of the task.  These are time estimates that somebody (or some group) decided on at some point in defining the project.  The chart shows the critical path of tasks in order to get an estimate of when the project will be completed.  You can see that some tasks can be run in parallel, so sometimes delays on these will not result in delays of the overall project.

What's wrong with this?  Under the right environment, one could argue that this would be very effective.  This "right environment" generally looks something like this:

  • You know exactly what you're going to build
  • You know exactly how long each task will take
  • The project won't change while it's underway

Hrm, this sounds a lot like bridge-building to me.  But software development is different.  We aren't building the same thing over and over again.  If we were, custom software development would be almost non-existent.  We don't know what we're going to build because our customers often don't know what they want!

There's a large component missing from this diagram.  Something that our customers care deeply about.  Do you know what it is?  That's right, it's business value!  Where is the business value depicted in this chart?  Surely it's important.  How else can we make scope changes and reorder the work if things aren't going as planned.  This graph has everything already ordered.  According to Gantt charts the business value only comes at the end of the project.  Our customer doesn't know what "Code Component X" means.  This is a developer task, and has no value statement associated with it.

Instead, what if we were to organize our work in terms of features.  A feature certainly has some notion of value.  You customer can easily tell you whether one feature is more important than another.

One could imagine a conversation like this:

You:  George, we're looking at our current progress and it looks like we're not going to meet our May 18th deadline for your demo with the VC guys."

Customer: What?!  Oh no this is terrible!  They might cut our funding!  We have to demo this stuff!

You:  Well, if we were to remove one of these 3 features, we could finish on time and have a demo ready.  Which one of these can wait a bit?

Customer: Well, it's critical that we are able to cancel a reservation.  And I think that we also really need to be able to see the most recent reservations placed, as that is something that the client will do daily, but searching reservations seems like it will be important, but not critical.  For now they can just find the reservations from the list.

Did you see what happened?  Magic just happened, that's what.  You and your customer just had a conversation about features and value.  You're able to adapt to the project's progress and work on the most critical features first.  The demo with the VC guys will happen and the most valuable features will be there.

How could this have happened in the Gantt chart above?  We might be in the middle of "Code Component X" when the demo comes.  Can we have the same conversation?

Lesson #1:  Task-based plans don't convey business value.  Feature-based plans do.

Okay, so now we have a list of features instead of tasks.  Don't we still need to know what is required to implement each feature?  Well yes, but not necessarily at the start of the project.  Breaking features down into tasks is an ongoing activity throughout the life of the project.

What's next?  Let's say we have 2 tasks on our project plan that look like this:

  • Build the New Reservation screen (3 days)
  • Build the New Booking screen (3 days)

Bookings and Reservations seemed like similar concepts, so we estimated them the same.  So we go off and build the New Reservation screen and we get hit with some complexity.  It takes us 5 days instead of 3.  What do we do about the New Booking Screen?  Is it likely that this screen will take us 5 days as well?  Or do we suck it in and try and work twice as fast to get this one done in 1 day, so our project plan doesn't go off track?

Once an estimate proves incorrect, any other estimate based on that one is now incorrect.  We can assume with high probability that building the Booking screen will take 5 days just like the similar Reservation screen.  The problem here is that we've estimated these tasks in duration rather than size.

Instead, let's give the Reservation screen an arbitrary number, like 5.  5 What?  I don't know...  5 Bananas.  5 Gummy Bears.  5 Stars.  Whatever it is, a 5 should mean something.  What's a 5?  It's about the size of that Reservation screen.  Oh ok, so this Booking screen must also be a 5.  And this Order Fulfillment screen, that's twice as big, so let's call that a 10.  What we're doing here is estimating in relative complexity, which far more stable a number.

Human beings can discern the size of something much more effectively than the time it will take to build it.  And as things progress on our project, the size generally stays constant.  We won't have to re-estimate these tasks unless the size changes.

Lesson 2:  Estimate in size, not duration.

OK, I can already hear you saying "But how can we tell our customer how long it will take if we don't estimate in duration?"  -- Well we do estimate in duration, but we also convey the confidence in this estimate.

CustomerSo how long will this take?

YouI don't know, we still don't have enough information about what to build, so I can't give you a firm number.

CustomerWell I have to know, how long do you think it will take?

YouMy best guess?  3-6 months.

Customer3-6 months?  That's a big difference!

YouAbsolutely.  We are estimating this at the worst possible position in the project.  Let's assume it will take 6 months for now.  After every iteration (2-4 weeks, typically) we will give you a more educated guess.

Granted, not all customers will be willing to do this, but you can spend more time discussing the process than I have here.

This is where Burndown charts become so effective.  A Burndown chart looks something like this:

burndown

This chart shows the hours remaining to complete the work during a given iteration.  Let's assume we attempted to complete 67 points (or Gummy Bears, whatever you decided on) of features.  When planning for hour iteration we broke these down into tasks and the team estimated 420 hours worth of work.  At the end of each day, the developers estimated how many hours remained on the tasks they were working on.  This continues every day.  Sometimes we uncover hidden work and this chart goes upward, as you can see in the picture.  Regardless of what we planned to do with our best intentions, we want to see actual performance.  If you were managing this project, would you feel comfortable with the current progress?

Try plotting a slope line on this image to see where we're headed.  Also plot the ideal line if we were to be on track.

burndown-projected

We're about 1/3 done with our first iteration, and we can already make solid assumptions of where we're headed.  It's clear that we aren't going to make our target, so it's time to have that conversation with our customer on what to pull.  This graph might also depict that we'll finish way too early, in which case the customer would be invited to select an extra feature to be developed in that iteration (provided the feature would fit in the slack room we had).

This chart shows clearly what is going on in the project, and you can easily expand this chart to encompass the overall project, not just the current iteration.  What if this graph represented the overall project and we were 1/3 done.  What would you do?

  • you could cancel the project -- it sucks, but it's better to get out now than to start  a death march project that ultimately won't finish in time and won't help the business.  Better to lose $150k than $500k any day of the week.icon-cornflower-blue
  • you could cut scope -- maybe changing the icons to cornflower blue wasn't as crucial to the business as we thought.
  • you could remove impediments -- what if you found that the developers are all experienced ReSharper users and they could be more productive if they all had licenses?  What if we had trouble getting a hold of the domain experts and we were waiting too long to get answers?  We could make some changes there to streamline the process.  Most business have a ton of fat in the process.  We just need to find it and cut it out.
  • you could add more resources -- if the end date is firm, then we might add some new folks to the project.  This is a bit of a dangerous move, as adding too many people to a project tends to make it later, but in a lot of cases, and extra pair of hands will help.  We can ask the team what type of person they need and try to fill that role.

ed-harris-apollo-13This type of actual progress vs. planned progress reminds me of that great scene in Apollo 13, where Ed Harris' character is asking whether or not a spacecraft could do what they were asking.  A squeemish representative cowardly states, "The LM was not designed for this..."

"I don't care what it was designed to do, I wanna know what it can do!"

The original plan is only useful enough until it doesn't represent reality any more.  What is useful is our empirical data.  Our actual progress.  That allows us to make informed decisions about what to do next.

Lesson 3:  Actual progress is infinitely more important than planned progress.

At the end of a few iterations we'll get a pretty good idea of how many points we can complete in an iteration.  This number is our velocity.

If we have identified 600 points of features to complete until we're "done," and we're completing an average of 60 points per iteration, then it doesn't take a rocket scientist to tell that we'll be done in 10 iterations.  That's a powerful statement.  After a few iterations you can tell your customer, "based on our current velocity and the amount of work we've identified, we'll be done July 27th."  The next iteration this date will get closer and closer to the actual "done" date.

Lesson 4:  Calculate your velocity and use that to plan for the future.

Burdowns (along with other related practices and ideas) are an incredibly effective tool to help you reign in your out of control projects.  Plans, road-maps, and timelines are all effective tools until they're not reality.  Learn from your past performance and project this onto the future.

I've only scratched the surface on how to effectively use burndowns on a project.  Some other important aspects are defining what "done" means and continuously improving the process.  If you're interested in implementing burndowns, I highly recommend you read these books:

Saturday, May 03, 2008

ASP.NET MVC Preview 2 Update

I’m upgrading Code Camp Server to the latest drop of ASP.NET MVC (which is just an interim release, so you might not yet care) but I wanted to get some first hand knowledge of how the new changes work out.

I won’t go over every change, because The Gu has a great writeup already.  But there are a few thoughts I’d like to share.

Routing

Routing is getting mature, and quick.  The fact that we can use this in our WebForms projects is really cool.  With routing getting more and more features, it is critical that you have extensive tests around your routes.  Imagine that you have an application already deployed.  A single change to the routing assembly (or the registered routes) can have a drastic effect on your application.  Existing links could be broken, new links might not work the way you expected, and you will severly cripple your search engine ranking.

Code Camp Server definitely needs to get an exhaustive set of routing tests to verify each of our URLs is functioning properly.

ActionResult

Instead of having controllers directly render views or redirect to another action, they have extracted this into ActionResult classes.  While the syntax is a bit quirky (“return RenderView”) this is a good design choice in my opinion.  If C# were as flexible as Ruby, we could still have the single “RenderView” method call, and the last statement would actually get returned to the calling method.

Our tests for Code Camp Server will be a lot cleaner.  No more test subclasses.  A lot less mocking as well, since now you can rely on plain old Asserts on the ActionResult .

This ActionResult change never made it to ComponentController though, but it will likely be there in the next drop.

Aside from the readability hiccup with “return” I don’t see any downsides to this change.  Anybody else experience any?

Validation Love from Steven Sanderson

Some people wonder how to do validation, since the existing ASP.NET Validators don’t work with ASP.NET MVC.  I ran across this, where Steven Sanderson shows how to do Model-based Client-side Validation in ASP.NET MVC using Castle Validator.  There’s even a 6–minute screencast!  Keep that kind of stuff coming Steve! 

Friday, May 02, 2008

I'm an Insider

Quick update:  I've been invited to join ASP Insiders!  I'm proud to be part of a select group of ASP.NET professionals who reach out to the community via forums, blogs, conferences, etc and are generally recognized experts in ASP.NET.



Some of the benefits of being an ASP Insider is to get in on some private discussion about design, new features, etc.  While I cannot publish any of this on my blog, I will be able to provide feedback in some areas (such as ASP.NET MVC).

Now, to go learn the secret handshake..
Remortgage - Renegade motorhomes - Credit Counseling - Credit Card Consolidation