interfacemoduleclrironruby

IronRuby needing a .NET Interface as an argument


I'm using the Revit API for extensible storage using IronRuby, and I think my problem is an IronRuby one. I'm trying to reproduce in IronRuby this C# example from Jeremy Tannik's Revit blog:

  // create a field to store a string map
  FieldBuilder fieldBuilder =
    schemaBuilder.AddMapField( "StringMap", typeof( string ), typeof( string ) );

. . .

  // set the value for this entity
  IDictionary<string, string> stringMap = new Dictionary<string, string>();
  stringMap.Add( "key1", "value1" );
  stringMap.Add( "key2", "value2" );
  entity.Set<IDictionary<string, string>>( field, stringMap );

When I try to do what I think is the same sort of thing in IronRuby:

# create a field to store a string map
schema_builder.AddMapField( "manually_checked", System::String.to_clr_type, System::Boolean.to_clr_type )

. . .

# set the value for this entity
xDict = Dictionary[System::String,System::Boolean].new
IDictionary_module = xDict.class.ancestors.detect  { |i| i.to_s == 
    "System::Collections::Generic::IDictionary[System::String, System::Boolean]" }
xDict.Add( "blah", true )

# all three of these fail with the same error
x.Set( "manually_checked", xDict )
x.method(:Set).of(Dictionary[System::String,System::Boolean]).call( "manually_checked", xDict )
x.method(:Set).of(IDictionary_module).call( "manually_checked", xDict )

All three of the ways I call Set() fail with the same message:

Unsupported type: System.Collections.Generic.Dictionary`2[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]] (InvalidOperationException)

Which makes me think that the "Dictionary`2" in the error message is a reference to xDict.class.ancestors[2], which is the position of IDictionary[System::String,System::Boolean] in the ancestors array.

So, my question is, is there an IronRuby syntax that will allow this, or have a bumped up against a showstopper because of the difference between a Ruby module and a .NET interface?


Solution

  • Your dictionary Add() is using an IronRuby string as the key parameter, but the dictionary is expecting a CLR string type. Add a "to_clr_string" call to your Ruby string to bring it in line with what's expected.