<< back to blog

Automating .NET development (and NHibernate) with IronRuby + Rake

Aug 17, 2009, .net ~ ruby ~ rake ~ nhibernate

Just the other day, I thought I'd try the latest IronRuby to see if I could start using this and Rake in my .NET projects. Low and behold, it's working great :)

Rake - A Developers Swiss Army Knife

Rake is like a swiss-army knife for developers. I use it to make tedious development tasks repeatable. As we all know, repeatability is king.

Here's some examples of what I've used Rake for during development:

  • Clearing out log files
  • Drop/Create development database
  • Loading up demo before a customer presentation
  • Listing which NHibernate entities are mapped to which tables
  • Running a particular batch of unit tests
  • Running background tasks for a solution, like rebuilding Lucene indexes
  • Generating reports on code statistics

Remember, the useful thing about Rake is that doing any of these things is usually a matter of simply typing rake logs:clear or similar. This saves your hours of pointing and clicking to do boring tasks.

Rake also has a few tricks up it's sleeve: you can automatically chain tasks together. For example:

task :test => [:clean, :drop_create_db, :build, :ndepend_report] do #... 

Your Rake scripts will also be able to make use of the thousands of Ruby gems out there. Well, actually, not all of them work ported to IronRuby .NET yet, but that's getting better all the time.

Getting IronRuby + Rake For .NET

This is a doddle.

  1. Download IronRuby and unzip to c:\IronRuby.

  2. Add c:\IronRuby\bin to your Windows PATH. Try to NOT put it in a folder with spaces in the name. Note: We're using IronRuby on both XP and Windows Server 2008 without problems.

  3. Install the 'Rake' gem by opening a command prompt and typing igem install rake. That's igem not gem.

Creating a Simple Rake Script

Using Rake only requires that you have one file called Rakefile.rb in the root directory of any .NET solution. A simple Rakefile could look like this.

# Rakefile.rb
require 'rubygems'  
require 'ftools'

task :default=>[:say_hi]

desc "Says Hi"
task :say_hi do 
    puts "Hi there. Rake is working."
    puts "Type rake --tasks."
end

desc "Count files of each type in this solution"
task :file_count do
   report = {}
   Dir['./**/**'].each do |f| 
     report[File.extname(f)].nil? ? report[File.extname(f)] = 1 : report[File.extname(f)] += 1 
   end
   report.each do |type, count|
     puts "#{type}: #{count}"
   end   
end

You can list available tasks in you IronRuby rake script by typing irake --tasks, which would output:

irake say_hi      Says Hi
irake file_count  Count files of each type in this solution

And you then can run an individual task by running rake filecount. Which would run the :filecount task and output the statistics.

This may all seem very simple, but what we now have is a sturdy framework for automating your development tasks and saving you a ton of time. You'll think very differently about your projects once you've used Rake for a while.

As a taster of the kinds of things you might use Rake for, take a look at the standard Rake tasks you get for a Ruby On Rails solution.

Using With Your .NET Solution Code

So far all this is very nice, but you could use standard Ruby rake to do all this stuff without the need for IronRuby. What IronRuby gives us is the ability to easily interoperate with .NET assemblies. And of course, that includes your own assemblies.

What I found very intersting is that I can use Rake to manipulate my NHibernate entities, and run other infrastructure code. So, if I want a script that can instantly bar all users for logging in to an intranet, that's really easy.

Rather than take you through a massively detailed tutorial, I'm just going to show you the main things I needed to do to get up and running with Rake in my solution.

The Rake File

This is very similar to the Rakefile.rb above. You can see some of the tasks that I'm using on a small intranet project Engine Room are doing.

You might notice that I'm using my standard NHibernate Unit Of Work (UoW) class here. That's fine, all of my application domain/infrastructure classes written in C# are available here now.

Also note that I'm leaning on Ruby naming conventions; IronRuby automatically translates .NET naming standards into Ruby naming standards, such as session.create_query rather than Session.CreateQuery. You can chose either, I just like to keep it Ruby stylee when using Ruby.

The All Important Setup File

You can see at the top of the previous Rake file I've added require 'rakesetup'. All that stuff doesn't work my magic, I needed to do some setup. I prefer to keep this out of the way - in a 'Rakesetup.rb' file I've created (it could be called anything really). Lets look at the setup code.

Some noteworthy points here are:

I want to pull in the namespaces that will be available to the Rakefile.rb file. I do this using lines like include Portal::Core::Domain::Entities.

I have different settings for production and development (in production we have a shared folder where all images/documents/etc live, whereas during dev we chuck these in App_Data).

For some reason IronRuby has problems resolving my DLLs, so I make sure the app runs from the Web bin folder by doing a Dir.chdir('Portal.Web\bin').

The path mappings are quite simple. I only run Rake from the solution root, which keeps resolving paths simple.

Conclusion

For a Ruby fan such as myself, being able to use IronRuby + Rake with .NET assemblies is pretty damn cool.

For those that love the goodness of Rake and who use .NET, this is all a good thing. Some of you may remember that James Gregory (Fluent NHibernate Hero!) and I looked at building a C# equivalent of Rake last year. This project is up on GitHub and is called Golem. I think that having IronRuby + Rake replaces the need for such a project, as long as you're happy to learn and write Ruby code.

It will be interesting to hear what the uptake on IronRuby + Rake will be, I know many .NET developers like to use traditional Ruby and Rake with their .NET projects, so there's definately an audience out there for it.

Have fun!

You may also like...

blog comments powered by Disqus