Forum: IronRuby Returning a Clr type in IronRuby

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Paul Cowan (Guest)
on 2009-03-03 17:18
(Received via mailing list)
Hi,
I am trying to return a CLR object from Iron Ruby.

I have the following CLR type defined in C#

public class BuildMetaData
{
    public string Description { get; set; }
}

I have the following IronRuby file:
$:.unshift(File.dirname(__FILE__) + '/../bin/Debug')
require 'mscorlib'
require 'Horn.Core.DSL.Domain'
class MetaDataFactory
    def return_meta_data()
        meta = Horn::Core::DSL::Domain::BuildMetaData.new
        meta.Description = "A description of sorts"
        meta
    end
end

I have the following test that is failing:
[Fact]
public void Then_a_build_metadata_object_is_returned()
{
   var engine = Ruby.CreateEngine();
   engine.Runtime.LoadAssembly(typeof (BuildMetaData).Assembly);
   engine.ExecuteFile(buildFile);
   var klass = engine.Runtime.Globals.GetVariable("MetaDataFactory");
   var instance = (RubyObject)engine.Operations.CreateInstance(klass);
   var metaData =
(BuildMetaData)engine.Operations.InvokeMember(instance,
"return_meta_data");
   Assert.Equal(metaData.Description, "A description of sorts");
}

It fails when trying to cast the object returned from IronRuby with the
following error.
System.InvalidCastException : [A]Horn.Core.DSL.Domain.BuildMetaData
cannot
be cast to [B]Horn.Core.DSL.Domain.BuildMetaData. Type A originates from
'Horn.Core.DSL.Domain, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=null' in the context 'LoadNeither' at location
'C:\Projects\horn\branches\rubydsl\src\Horn.Dsl.Specificatioin\bin\Debug\Horn.Core.DSL.Domain.dll'.
Type B originates from 'Horn.Core.DSL.Domain, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=null' in the context 'Default' at
location
'C:\Users\paul.cowan\AppData\Local\Temp\gjpo5svj.0zd\Horn.Dsl.Specificatioin\assembly\dl3\6d8ae49c\7acadf2b_c798c901\Horn.Core.DSL.Domain.DLL'.

The only way I can access the members of the BuildMetaData is using
reflection.

If you look at the error message, both types are created in different
locations.

Is this possible in IronRuby yet?

Cheers

Paul
Tomas M. (Guest)
on 2009-03-03 20:26
(Received via mailing list)
The problem is that CLR/Mono assembly loader loads the assembly twice
into 2 different contexts: "LoadNeither" and "Default".
Therefore there are actually 2 different types "BuildMetaData" in
system.

require 'Horn.Core.DSL.Domain' uses Assembly.LoadFrom to load the
assembly, which loads it to one context.
A static assembly reference (in C#) is loaded via Assembly.Load, which
loads to a different context.

You can use Kernel#load_assembly or require '<full assembly name>' to
invoke Assembly.Load.

Tomas

From: removed_email_address@domain.invalid
[mailto:removed_email_address@domain.invalid] On Behalf Of Paul Cowan
Sent: Tuesday, March 03, 2009 6:53 AM
To: removed_email_address@domain.invalid
Subject: [Ironruby-core] Returning a Clr type in IronRuby

Hi,
I am trying to return a CLR object from Iron Ruby.

I have the following CLR type defined in C#

public class BuildMetaData
{
    public string Description { get; set; }
}

I have the following IronRuby file:
$:.unshift(File.dirname(__FILE__) + '/../bin/Debug')
require 'mscorlib'
require 'Horn.Core.DSL.Domain'
class MetaDataFactory
    def return_meta_data()
        meta = Horn::Core::DSL::Domain::BuildMetaData.new
        meta.Description = "A description of sorts"
        meta
    end
end

I have the following test that is failing:
[Fact]
public void Then_a_build_metadata_object_is_returned()
{
   var engine = Ruby.CreateEngine();
   engine.Runtime.LoadAssembly(typeof (BuildMetaData).Assembly);
   engine.ExecuteFile(buildFile);
   var klass = engine.Runtime.Globals.GetVariable("MetaDataFactory");
   var instance = (RubyObject)engine.Operations.CreateInstance(klass);
   var metaData =
(BuildMetaData)engine.Operations.InvokeMember(instance,
"return_meta_data");
   Assert.Equal(metaData.Description, "A description of sorts");
}

It fails when trying to cast the object returned from IronRuby with the
following error.
System.InvalidCastException : [A]Horn.Core.DSL.Domain.BuildMetaData
cannot be cast to [B]Horn.Core.DSL.Domain.BuildMetaData. Type A
originates from 'Horn.Core.DSL.Domain, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=null' in the context 'LoadNeither' at location
'C:\Projects\horn\branches\rubydsl\src\Horn.Dsl.Specificatioin\bin\Debug\Horn.Core.DSL.Domain.dll'.
Type B originates from 'Horn.Core.DSL.Domain, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=null' in the context 'Default' at
location
'C:\Users\paul.cowan\AppData\Local\Temp\gjpo5svj.0zd\Horn.Dsl.Specificatioin\assembly\dl3\6d8ae49c\7acadf2b_c798c901\Horn.Core.DSL.Domain.DLL'.

The only way I can access the members of the BuildMetaData is using
reflection.

If you look at the error message, both types are created in different
locations.

Is this possible in IronRuby yet?

Cheers

Paul
Paul Cowan (Guest)
on 2009-03-03 21:53
(Received via mailing list)
I was running the test using the R# test runner and once I turned off
the
shadow-copy assemblies being tested option then the test now passes.



2009/3/3 Tomas M. <removed_email_address@domain.invalid>
This topic is locked and can not be replied to.