Welcome to MSDN Blogs Sign in | Join | Help
Ruby on MEF: Hybrid Application

Since the last installment in this little series, I've started to consider how Ruby/C# hybrid MEF applications might look.

The result is yet another component-based calculator:

image

Besides the Radiohead arithmetic, there is one reason to get excited...

image

Ruby parts! (I bet you hadn't guessed.)

The Ruby-based export and import features are heading towards a fairly natural syntax. IOperation, for example, is a regular .NET interface type:

image 

Let's take a look at how the Ruby implementation is woven into the app.

Configuration

This is still a work-in-progress, so configuration is basic. All of the Ruby parts are loaded from a single file that is fed into the RubyCatalog:

image

The calculator_ops.rb file contains part definitions like Multiply from above.

An additional catalog adds all of the C# parts to the composition as well:

image

Main Window

The main window is a typical WPF Window that Imports a list of operations:

image

Because the MainWindow is instantiated and composed by MEF, all known exporters of IOperation will be provided, regardless of the language they're implemented in.

Bi-Directional Composition

You'll notice that the MainWindow class implements the IErrorLog contract. This allows messages from the parts to be presented to the user:

image

Parts that wish to access the IErrorLog service from Ruby can import it:

image

The integration (and IronRuby in general) treats interface contracts as Ruby Module objects, so the IErrorLog used by the Divide part could be implemented by a Ruby object, although I haven't tested that case.

Fanatics take note: I did attempt to use IronRuby's case-transforming features to allow Symbol and Apply() to be specified in their natural Ruby forms (symbol and apply()) but had no success. Hopefully I'll resolve this in a future version.

Monkeypatching the Export Type

I can't say whether this will turn out to be a good move or not, but right now it seems reasonable.

Notice this method call:

image

In order to support MEF's lazy-instantiation feature, the @error_log attribute needs to be of type System::ComponentModel::Composition::Export, which will supply the actual instance when it is required through the get_exported_object() method. Calling @error_log.get_exported_object.add_message felt decidedly unnatural, so I've added method forwarding to the Ruby version of the Export class:

image

I've had to do some type aliasing to disambiguate Export from Export<T>, but otherwise this is straightforward. Rubyists, please weigh in and let me know if this implementation is less-than-desirable :)

Source Code

Once again you can download the full source code for this article from SkyDrive.

Published Tuesday, December 23, 2008 12:20 AM by niblumha

Filed under: ,

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

No Comments

Leave a Comment

(required) 
required 
(required) 
Page view tracker