Re: InternalsVisibleTo

Jimmy,

So I decided to debug this out a bit for myself. Before I go too far,
here
is how my require headers are setup:

require ‘System.Xml.Linq, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089’
require ‘System.Data.DataSetExtensions, Version=3.5.0.0,
Culture=neutral,
PublicKeyToken=b77a5c561934e089’
require ‘System.Data, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089’
require ‘System.Xml, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089’
require ‘System.Drawing, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a’
require ‘System.Windows.Forms, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089’
require
‘C:\Users\pinvoke\Desktop\Rspec_Project_Runner\cmd_parser\bin\Debug\CmdParser.dll’
require
‘C:\Users\pinvoke\Desktop\Rspec_Project_Runner\rspec_project_runner\bin\Debug\rspec_project_runner.exe’

Inside of my IronRuby specs, there is a call that, in ruby looks like
this:

    rargs = ['-o', 'C:\Users\pinvoke']
    args = System::Array[System::String].new(rargs)
    p = Rspec::Project::Runner::ProgramArguments.Parse(args)

The call to assign the results of Parse to P always fails unless I

a) Do what Ivan suggested and copy to the bin folder
b.) Modify ir.exe.config to include the path to the actual .dll

I was reading the source code this evening and noticed that during the
RubyContext buildup it only includes the following paths to resolve
references:

context.Loader.GetLoadPathStrings()
{string[4]}
[0]: “F:/ironruby-ironruby-178b744/Merlin/Main/Languages/Ruby/libs/”
[1]:
“F:/ironruby-ironruby-178b744/Merlin/External.LCA_RESTRICTED/Languages/Ruby/redist-libs/ruby/site_ruby/1.8/”
[2]:
“F:/ironruby-ironruby-178b744/Merlin/External.LCA_RESTRICTED/Languages/Ruby/redist-libs/ruby/1.8/”
[3]: “.”

I assumed this is was why if I dump my .dll into any of those paths it
resolves.

Then when I looked at the loaded files, everything looked like it loaded
correctly:

[2]: "System.Xml.Linq, Version=3.5.0.0, Culture=neutral,

PublicKeyToken=b77a5c561934e089"
[3]: “System.Data.DataSetExtensions, Version=3.5.0.0,
Culture=neutral,
PublicKeyToken=b77a5c561934e089”
[4]: “System.Data, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089”
[5]: “System.Xml, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089”
[6]: “System.Drawing, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a”
[7]: “System.Windows.Forms, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089”
[8]:
“C:\\Users\\pinvoke\\Desktop\\Rspec_Project_Runner\\cmd_parser\\bin\\Debug\\CmdParser.dll”
[9]:
“C:\\Users\\pinvoke\\Desktop\\Rspec_Project_Runner\\Specs\\CmdParser_spec_helper.rb”
[10]:
“C:\\Users\\pinvoke\\Desktop\\Rspec_Project_Runner\\rspec_project_runner\\bin\\Debug\\rspec_project_runner.exe”
[11]: “rspec_project_runner_spec_helper.rb”

Here is where it gets fun!

The problem appears to be in the way IronRuby is resolving assembly
references from other already loaded assemblies. That is, if I make the
above spec calls (rargs /args/ p) the application blows up w/o the
CmdParser
assembly in the path. The thing is that all the .Parse(args) method
call is
doing is a wrapper to call into another assembly… the one that blows
up as
not being found.

So, I decided to see what happened if I call the methods from the
CmdParser
assembly directly and… everything works fine. Regardless of which
path
the file is in :slight_smile:

If I wasn’t so tired I would try and trace back how the resolve was
working
and why it wasn’t checking the loaded files… however I am exhausted
and
it’s way past my bed time.

If this helps, here is the Fusion Log that got dumped:

=== Pre-bind state information ===
LOG: User = veritas\pinvoke
LOG: DisplayName = CmdParser, Version=1.5.0.0, Culture=neutral,
PublicKeyToken=null
(Fully-specified)
LOG: Appbase =
file:///F:/ironruby-ironruby-178b744/Merlin/Main/bin/Debug/
LOG: Initial PrivatePath = NULL
Calling assembly : (Unknown).

LOG: This bind starts in default load context.
LOG: Using application configuration file:
F:\ironruby-ironruby-178b744\Merlin\Main\bin\Debug\ir.exe.Config
LOG: Using machine configuration file from
C:\Windows\Microsoft.NET\Framework\v2.0.50727\config\machine.config.
LOG: Policy not being applied to reference at this time (private,
custom,
partial, or location-based assembly bind).
LOG: The same bind was seen before, and was failed with hr = 0x80070002.

-Andrew

The call to assign the results of Parse to P always fails unless I

a) Do what Ivan suggested and copy to the bin folder
b.) Modify ir.exe.config to include the path to the actual .dll

I would suggest neither of these =P See below.

I assumed this is was why if I dump my .dll into any of those paths it resolves.

Resolving DLLs should behave the same way as resolving Ruby libraries;
it has to be on the load path. As you saw in the debugger, the load path
is preset with the LibraryPaths value that is in the config, but it’s
preferred to modify the load path by appending string to the $LOAD_PATH
(or $: shorthand) variable, rather than modifying the config file.

Consider the following directory structure:
/dlls/foo.dll
/bar.rb

Where foo.dll was compiled from this C# code:

public class Foo {
public static void Bar() {
System.Console.WriteLine(“In Bar”);
}
}

If foo.rb just looked like this:

require ‘foo.dll’
Foo.bar

… and ir.exe is anywhere but the dlls directory you’d get this error:

PS C:\temp> ir .\bar.rb
:0:in `require’: no such file to load – foo (LoadError)
from ./bar.rb:1

However, if you add “dlls” to the load path first:

$LOAD_PATH << File.dirname(FILE) + “/dlls”
require ‘foo.dll’
Foo.bar

Then all will work:

PS C:\temp> ir .\bar.rb
In Bar

Notice that the first line “File.dirname(FILE)” to make the “dlls”
path relative to the current file. Then doing “require ‘foo’” will look
in the dlls directory.

Does that solve your problem?

~Jimmy