Using C# / .NET libraries within IronRuby

Saturday, July 18th, 2009

I attended my first VistaSquad meeting on Wednesday. Part of the evening was a very interesting talk from @ben_hall on IronRuby, which among many other things included how to use any .NET CLR libraries direct from your IronRuby script (running via the .NET DLR).

Whilst my example below is extremely trivial, it shows how you might make use of any existing libraries within your Ruby scripts. This same technique applies to any .NET libraries, whether they’re custom, part of the framework, or created by your gran. I don’t think I really need to sell it in – but I love the flexibility that this provides.

So to get to the example, this simple piece of C# displays all the prime numbers between 0 and maxNumber:

public int[] DisplayPrimeNumbers(int maxNumber)
{
    int max = maxNumber;
    List previousPrimes = new List();
    previousPrimes.Add(2);
    if (max < 2) return null; // none
    for (int i = 3; i  maxDivisor) break;
            if ((i % previousPrimes[j]) == 0)
            {
                foundDivisor = true;
            }
        }
        if (!foundDivisor)
        {
            previousPrimes.Add(i);
        }
    }
    return previousPrimes.ToArray();
}

We can build that up into a class library and using IronRuby, manipulate the return of the method the same as though we had been running native ruby.

require 'mscorlib'
require 'CSharpLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null';
prime_numbers = CSharpLib::PrimeNumbers.new
(prime_numbers.DisplayPrimeNumbers 20).each do |num|
	puts num
end

You can download the full sample below, a C# console app is also included for completeness (although isn’t a part of the IronRuby process). You will of course, need to download IronRuby first, and add the installed bin/ folder to your path. Then just change to the <sample>/ruby/ directory, and run it with:

ir run.rb

It’s probably worth noting that IronRuby is still a way off from a 1.0 release, but it’s already very usable and looking rather cool. Since it’s on my recent //TODO list, I’ll be doing a few more examples here – next time turning this one its head and executing your ruby scripts from within C#. In the meantime, you can check out Ben’s set of slides from Wednesday on Slideshare.

//TODO: Learn, play, discuss.

Saturday, July 11th, 2009

Somewhat inspired by Mike Taulty’s blog, I’ve decided I should throw my Tech TODO list at the world, because it might encourage / guilt me into doing some of them, as well as provide a preview on what this blog might be including over the next few months.

So all of these are technologies, packages, or platforms I want to be checking out in the not-to-distant future.  In no particular order, they’re bound to be added to as I go and quite possibly ignored as well.

  • .NET
    • ASP.NET MVC
    • ADO.NET Data Services
    • F#
    • IronRuby
    • Open-sourcing a simple XML resource provider (CodePlex)
    • .NET 4
      • Windows Communication Foundation
      • Entity Framework
      • Parallel Extensions
  • Gallery3
    • Module development
      • Migrate Twitter module
      • Migrate auto-GPS-tagging module
    • Theme development
  • Google Wave

Gallery2 remote API C# wrapper

Monday, June 29th, 2009

I stumbled across the Gallery.NET Toolkit on Twitter, while I should have been doing something more useful; some great work from @rmaclean (thanks for sharing / codeplexing  it).

The API wraps up a lot of the Gallery2 remote services into some easy to use C# functions.

Actions a = new SADev.Gallery2.Protocol.Actions("http://www.blakepics.com");
string authToken = a.Login("*************", "*************").AuthToken;
a.FetchAlbums(authToken).Albums.ForEach(
    album =>
    {
        Console.WriteLine(album.Title);
        a.FetchImages(authToken, album.Name).Images.ForEach(image =>
            Console.WriteLine("\t" + image.Url)
        );
    }
    );
Console.ReadKey();

Hopefully I’ll find an excuse to use this one day.

Getting document reports from Amazon Seller Central SOAP services (C#)

Sunday, March 22nd, 2009

Developing against the Amazon API becomes a lot more straightforward with being able to get at the errors with your XML documents. Validating against the XSDs is only part of the solution, but even downloading reports can be tricky. Trouble is, the documentation from Amazon is a very closed & private sort of affair – sometimes out of date and sometimes very sparse. Perhaps they should think about a wiki :)

Getting at your reports consists of two parts, firstly – use the Document ID (long) you got from posting the XML in the first place.

public DocumentProcessingInfo DocumentStatus(long DocumentID)
    {
        //Setup the service interface, set the URL of the service
        //and add our credentials.
        merchantinterfacedime myAmazon =
            new merchantinterfacedime();
        myAmazon.Url = ConfigurationManager.AppSettings["URL"];
        myAmazon.Credentials =
            new NetworkCredential(
                ConfigurationManager.AppSettings["UserName"],
                ConfigurationManager.AppSettings["Password"]);
        //Setup our merchant details.
        Merchant myMerchant = new Merchant();
        myMerchant.merchantIdentifier =
            ConfigurationManager.AppSettings["MerchantIdentifier"];
        myMerchant.merchantName =
            ConfigurationManager.AppSettings["MerchantName"];
        //Send it all off to Amazon.
        DocumentProcessingInfo myStatus =
            myAmazon.getDocumentProcessingStatus(
            myMerchant, DocumentID);
        //Return the status of the document.
        return myStatus;
    }

This will give you the status of your upload, as well as whether it’s complete or not. It also gives you another document ID, which you can use to get at your much-needed reports.

public string GetDocument(string id) {
        StringBuilder report = new StringBuilder();
        merchantinterfacedime myAmazon =
            new merchantinterfacedime();
        myAmazon.Url = ConfigurationManager.AppSettings["URL"];
        myAmazon.Credentials =
            new NetworkCredential(
                ConfigurationManager.AppSettings["UserName"],
                ConfigurationManager.AppSettings["Password"]);
        //Setup our merchant details.
        Merchant myMerchant = new Merchant();
        myMerchant.merchantIdentifier =
            ConfigurationManager.AppSettings["MerchantIdentifier"];
        myMerchant.merchantName =
            ConfigurationManager.AppSettings["MerchantName"];
        ReferencedBinary incomingDoc = new ReferencedBinary();
        // the seven-digit string is the document ID number
        myAmazon.getDocument(myMerchant, id, out incomingDoc);
        IEnumerator enumer = myAmazon.ResponseSoapContext.Attachments.GetEnumerator();
        while (enumer.MoveNext())
        {
            // Print the document to standard out
            Attachment downloadedDoc = enumer.Current as Attachment;
            StreamReader r = new StreamReader(downloadedDoc.Stream);
            report.Append(r.ReadToEnd());
        }
        return report.ToString();
}

And tying it all together:

long amazonId = #######
string report = GetDocument(DocumentStatus(amazonId).processingReport.documentID);

Your report will be in XML, and give you any validation errors that might be preventing your feed from working properly, as well as some very helpful status on the number of items processed. How did you ever live without it?

Twitter – Conversation in the Machine

Thursday, July 31st, 2008

It’s another of those life-changing technologies which will not only improve the way you interact your fellow humans across the planet, but also shape and change the web as we know it for a brighter future beyond our current limited borders.

No it’s not.

It’s a micro-blogging tool which performs about the same function as your Facebook status, with a bit more history and more conversation potential than real speaking. It also falls into the category of “shiny web things” that the magpie’s of the Internet world run bounding towards with wings flapping, declaring their undying allegiance and overwhelming excitement about the grand new era of technology, society and communication.

I am said magpie. I just haven’t had much use for it, so whilst most people are bounding towards Pownce with their wings wide open, I’m still trying to find an excuse.

My Twitter feed is decidedly empty, having originally opened it as a way only of updating my Facebook status before I realised that was syndication for the sake of it (See integrations with BrightKite, Loopt, and Flickr integration for reference). But I do get a kick out of things like the Tower Bridge Tweets. The wonderful thing about this Web 2.0 stuff is that you don’t have to use any of it for what it was intended for (which is usually so vague and fluffy, it only really starts to take shape after the rules have been broken).

So I grabbed a copy of the Net::Twitter module for Perl and before you know it, my script that monitors if the Wifi connection on the Blakepics server had gone down was happily tweeting away with only three more lines of (my) code.

use Net::Twitter;
my $twit = Net::Twitter->new(username=>"username", password=>"password", source => "DowntimeMonitor" );
$twit->update("Internet connection ".($state ? "is now up" : "has been restarted"));