Ruby Utilities for .NET Developers, Part 1: Rake

I’m working on some side projects at night and enjoying the chance to try out some new tech before inflicting it upon my coworkers. One such tech is using Rake as a build scripting language instead of NAnt/MSBuild for .NET projects. Some smart people that appear in my Google Reader seemed to like it but I hadn’t yet had a chance to review it for myself.

It’s been really pleasing to work with so far. The Ruby syntax is terse and concise without being opaque, and the benefits of no longer “programming in xml” via NAnt seem obvious now — if you need functionality not available via the standard build library, go write it yourself in Ruby. It’s refactoring-friendly and readable. I still use the VS2008 IDE for most of my work, so I am missing syntax highlighting of Ruby files, but other than that it’s fairly easy to work with.

Here’s the bare minimum of what you need to add Rake to a .NET project:

1) I structure my project with an initial folder structure that looks sort of like this ( blatantly ripped from TreeSurgeon ):

/lib <– 3rd party dlls go here

/src <– solution file goes in here, with VS.NET projects underneath

/tools <– build-related files go here

2. To this project structure, in the root with those three folders, I put a file named “Rakefile”. No extension.

3. In my VS.NET solution, I choose to “Add existing file” at the solution root in Solution Explorer and choose Rakefile. This is to make it easy to edit from the IDE and is not required.

4. In the Rakefile file, I add some bootstrap code like this:


require 'rake/clean'

MSBUILD_PATH = 'C:/Windows/Microsoft.NET/Framework/v3.5/msbuild.exe'
BUILD_DIR = File.expand_path('build')
SOURCE_DIR = File.expand_path('src') 

CLEAN.include(FileList[File.join(BUILD_DIR, '*')])

task :default => [:clean, :build]  

desc "Compiles source files"
task :build do
  solution = File.join(SOURCE_DIR, 'RENAME-ME.sln')
  sh "#{MSBUILD_PATH} /property:WarningLevel=4;OutDir=#{BUILD_DIR}/ #{solution}"
end 

“REPLACE-ME.sln” needs to be replaced with the name of your Solution.

5. Now it’s Ruby time. If you don’t have it installed, your best bet is the Ruby One-Click installer.

6. Finally, open a command shell to your project root and type in “rake”.  You should see MSBuild’s output from compiling your project. Success!

I hope this has been helpful. I’m planning to continue this series with one more post on using ActiveRecord migrations for your .NET projects as well.

One-off Projects and Throwaway Code

Something I’ve struggled with in the past is how to best handle the dichotomy between “Real Projects” and “One-Offs”. Real Projects are the ones that you plan on saving and maintaining to stand the test of time. One-Offs are the ugly and hastily assembled scripts who are discarded after their first run.

Except that, very often, they aren’t. On more than one occasion, I’ve had to go back and add features or fix bugs in apps that were never supposed to make it past their first day. It was painful to do this many times because the code that was originally written was ramshackle and slapped together, since it was supposed to be a Git’R'Done.

Of course, you don’t have perfect foresight, and neither does your team, your PMs, or your boss. You don’t always know what’s going to be useful later and what’s going to be never touched again. Analyzing the decision forever trying to prognosticate the future of your app isn’t an option.

So what kind of ways can you handle this problem?

One way is to write every app as though  it was going to be maintained perpetually, spending time upfront to carefully design and refactor the code. In the Pro column, this ensures that you never have to eat the cost of fixing messy code after you decide that it’s going to need some more features after all. Unfortunately, it also means that you could be wasting a lot of time in design for applications that will not change. Applications that don’t need to change don’t need good design — in fact, good design is wasted on them because it is a  real cost that you have essentially squandered — it’s like buying replacement insurance for a roll of paper towels.

Another way is to write every app as though it were a one-off and then only refactoring the ones you come back to often. This has an advantage in that no design is ever wasted, and thus no dev effort/time/cost is spent unnecessarily. That does mean that more often than not, you’re going to have to spend some extra time you might not have figured on spending cleaning up a slipshod app to become something that you’re not going to hate maintaining after the first few features.

Finally, a last way is to automate the creation of a new solution/project using a framework like SharpArchitecture, TreeSurgeon, or Rails. Take the libraries and scaffolding you use on all your Real Applications and codify those opinions into an app generator that can spit out a new solution with everything it needs, even if you’re not usually it initially. Use that generator for all new applications. That way, even if you guess wrong and a One Off turns into a Real Application, you’ve hedged  your bets somewhat in that you don’t have to spend a lot of time getting your tools in place and framework; you should already have a place for tests and a test framework in place, for instance.

I’ve tried all of these approaches over the years and am leaning towards the last one as the one that gets me into that 80/20 spot where most of the time there’s not a lot of wasted effort. What do you do to handle One Offs in a pragmatic and repeatable way?

Quality Time with my Podcasts

I’ve been listening to a lot of podcasts lately. It’s been hard to find time outside of work to get some learning done, but I’ve found that with the new iPhone 2.2 update came the ability to stream podcasts live from iTunes over the 3G connection, so I’ve been taking full advantage to get my learn on while I’m bumper deep in Greater Dallas traffic. I thought I’d list some of the ones that I thought were worth the time.

raleigh.rb : Ruby/Rails oriented, but there’s some great content for all developers, like Fear of Programming, which explores psychological roadblocks that we all come across when trying to write code, and I Can Has Productivity?, which discusses ways to squeeze a little more efficiency out of your coding sessions. Domain Modeling with REST has also been a favorite, it’s a good companion piece to DHH’s talk on CRUD and Restful Domain Modeling.

altdotnet podcast / rubiverse: Mike Moore hosts both of these podcasts, the first covering methodology and topics relevant to those who want to really push the boundaries of what is possible in .NET development and projects. Sometimes controversial and always thought provoking. The second is Ruby/Rails oriented, and there’s not many podcasts in the series, but each is an enlightening discussion with newsworthy and fascinating individuals in the Rails world. Highly recommended.

Herding Code: I just discovered this one, but the most recent episode covers the FubuMVC framework, which I hadn’t even heard of until today. It’s hosted by a whole bunch of bloggers that I happen to subscribe to, so I have high hopes for the rest of the content.

Learning Rails: It’s hard to find audio-only podcast content that covers learning a new language or framework, but this is one of the best I’ve found to date. The first seven or so episodes are a great introduction to finding out what Rails is all about.

Rails Envy: Fun and topical. It covers the latest happenings in the Rails community and reviews products, plugins, and other stuff in the Rails ecosystem. It’s very fast paced and keeps your interest while covering a lot of ground.

I guess quite a few of those turned out to be Rails-oriented, but I think it’s useful to find out what other communities value. Getting another frame of reference on web development is always a a good thing, right?

Uncle Bob on Hanselminutes

A small disclaimer: I am a total fanboy forRobert “Uncle Bob” Martin and Scott Hanselman, as well as SOLID principles, so imagine my nerd-glee when I rolled through my news reader yesterday and saw that Uncle Bob had done an interview on Hanselminutes about SOLID. It’s the hat trick, the trifecta, the code monkey extravaganza, and it delivered.

If you’re a developer, whether you know SOLID principles through and through, or you have never heard of them, go listen. It is as concise a treatment of the subject as I have found so far, and it does a great job of distilling design guidelines that sound lofty into just what you need to know. I liked how Scott took on the role of the “average developer” who had never heard of these things before, asking the same kind of questions that people would typically ask upon being first presented with the material.

Needless complexity and taking the first bullet

Ray Houston blogged recently about needless complexity in the design of code. The question at hand was if a particular function had too many responsibilities, violating the Single Responsibility Principle (SRP). The conclusion reached was that separating each and every responsibility into an individual class leads to a million tiny classes, each with one method, none of whom carries their weight. The c2 wiki calls this ravioli code, the opposite of the classic spaghetti code.

Clearly there are no hard and fast rules here. You could err on the side of making too many classes and presuming that every change is equally likely, or you could err on the side of making the code naive and resist breaking anything apart. So when do you break responsibilities into separate classes? When you think they are likely to change for different reasons. Unfortunately for us, no one can predict the future. Some likely changes are always obvious to us, but some we are not so sure about.

Fortunately, the Agile Patterns, Principles, and Practices book referenced in Ray’s post brings us some more guidance here. When you aren’t truly convinced that a piece of code needs to be flexible, err on the side of simplicity, resist breaking it apart, and “take the first bullet”. Let a change come through requiring more flexibility and then, at that point, go ahead and protect yourself from future changes of that type. It doesn’t solve every problem or protect every design, but it’s a great defense against unnecessary complexity.

Hoff on Software

Sometime in the depths of night this week, AutoRevo co-founder Mark Hoffman found the time to establish a blog! Now that the shock has worn off, I’d like to bid him welcome and throw a link his way so that both of my readers (hi mom!) can take a look.

He’s already tearing my posting schedule a new one and he’s not even been doing this a week. Time for me to get off my duff…

Don’t be a red shirt

AutoRevo CTO Mark Hoffman and I had a short Q&A session with the audience immediately after his presentation in Chicago last week. I enjoyed getting to discuss unit testing threaded code and grid frameworks with other developers who have been fighting the same battles we have been at AutoRevo. It’s not often that I get to hear about how other teams approach eBay application development and the kinds of apps they’re writing.

If only everyone was there to actually engage in discussion. Months before the presentation, The Hoff and I had decided to bet that the dreaded Red Shirt would attend. This “Red shirt” epithet traces its roots back to a  yarn Rob Conery spun about Scott Hanselman shutting down a heckler at one of his talks. The eventual victim in this story is instantly identifiable to anyone who’s ever attended any gathering of geeks where one geek has to speak in front of the other geeks. The “Red Shirt” is THAT GUY.

You know THAT GUY: the one who’s there not to learn or to ask questions, but to prove that his propeller spins fastest; he’s the smartest guy in the room, the one who should really be speaking. The one whose every raise of the hand and comment is accompanied by groans or eyerolling from everyone else in attendance. The one who criticizes without offering alternatives because it’s far easier to bulldoze than to build.

It’s hard to imagine a red shirt in any other sort of setting. The AMA was holding a much larger conference at the hotel we stayed in, and I couldn’t help but wonder if they experienced the same sort of issues. Did one doctor heckle another as he was giving a talk on medical procedures? It didn’t seem likely. There’s just something about developers, or maybe engineers in general, that makes us excessively hesitant to accept our peers as authorities on anything. It sails past a healthy skepticism towards conventional thinking, then over that line and rocketing onward towards solipsism.

I’m not saying that it’s wrong to ask questions. There’s a difference between an honest question and one designed to make someone feel like a jackass. If you have an opinion, be prepared to back it up with solid evidence. Telling someone their ideas are stupid is only useful if you have something real to offer that is better.

Ask questions. Drill down. Just don’t be a red shirt. Like the somewhat more well known red shirts, they don’t contribute to the conversation and nobody misses them when they’re gone.

Firefox 3 slow in ASP.NET Development Server

Ever since I started using Firefox 3 as my default “Browse With…” choice in VS2008, I’d noticed that pages loaded really, really slowly. I pulled out the big guns and fired up YSlow to figure out what the holdup was. We’re talking about 20-25 seconds to render around 200k of data.

YSlow showed me that each individual request to the server took over 1 second each, but when I loaded the same page in staging it took only 3ms. Clearly, the problem was related to Cassini, the VS2005/2008 built-in web server.

Sure enough, I found the answer after I figured out the correct question to ask (for the record, it was “Cassini Firefox Slow”). Since “Cassini” wasn’t the first thing I thought of when I began researching the problem, in the interest of increasing the visibility of the answer I’ll include it here, because it was driving me insane.

Enter “about:config” in the address bar to go to your Firefox configuration page and then filter by “ipv6″. Set “network.dns.disableIPv6″ to “true”.  Enjoy development again.

Live from Chicago

I’m currently attending the eBay Developers’ conference in Chicago, to assist AutoRevo’s CTO Mark Hoffman with his presentation on building scalable applications to talk to the eBay API. I’ll post a link to the published presentation materials as soon as I find them.

Basically we were talking about how we solved scalability in a practical and effective way using a small framework of our own devising. The source code was tiny enough that it could be written over a long weekend, yet it allows us to easily and quickly add commodity servers to solve large problems more rapidly.

A big thanks to all the developers who attended the talk! I enjoyed getting to meet and discuss the topic with other people with the same problems and concerns; I just wish we had more time to talk about it all.

Investigating PEX and Agile

PEX, short for Program Exploration, has arrived from Microsoft Research. Along with the download is a tutorial PDF explaining how it is used. I’ve been interested in this project since it was announced, but warily. Microsoft’s understanding of the purpose of unit tests has been iffy for years ( for example, see the MSTest Unit Test Generation Wizard included in VS2005/2008 ). Did they get this right or is this more of the same “tools over knowledge” that we’ve come to expect?

I’ll spend some time going over the documentation materials and trying it for myself, but I wonder if people who are more experienced with TDD would see some things I don’t. I’d really like to hear some longtime .NET agilists‘ take on this product.