mcneel / rhino.inside

Sample Projects for Rhino.Inside
MIT License
382 stars 169 forks source link

Using Rhino.Inside + Grasshopper from a referenced project #279

Closed DanielAbalde closed 3 years ago

DanielAbalde commented 3 years ago

Hi there, I have a WIP project for debugging that execute GH definitions inside UnitTest methods using the MSTest framework, let's call it Project A (Tenrec), is where Rhino.Inside things happens. I have a secondary project, called project B (SampleTest1), which is a sample use case.

The Rhino.Inside part works as expected in project A but when I use it from project B, I got a .dll not found exception. System.IO.FileNotFoundException: Could not load file or assembly 'Grasshopper, Version=7.6.21127.19000, Culture=neutral, PublicKeyToken=dda4f5ec2cd80803' or one of its dependencies. The system cannot find the file specified.

I have the same references in both projects, for instance, what I did was to get the nuget package of RhinoInside and update its dependencies (Rhinocommon, RhinoWindows and Grasshopper) to the latest stable release 7.6.21127.19001. However, the version that is being referenced in mi project is 7.6.21127.19000. I don't know if this is an issue or it is irrelevant, but just in case I show you:

image

In both projects, the package.config looks like this:

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="Grasshopper" version="7.6.21127.19001" targetFramework="net48" />
  <package id="MSTest.TestAdapter" version="2.2.4" targetFramework="net48" />
  <package id="MSTest.TestFramework" version="2.2.4" targetFramework="net48" />
  <package id="Rhino.Inside" version="7.0.0" targetFramework="net48" />
  <package id="RhinoCommon" version="7.6.21127.19001" targetFramework="net48" />
  <package id="RhinoWindows" version="7.6.21127.19001" targetFramework="net48" />
</packages>

THE PROBLEM And when I run a test in project B that looks like this:

  [TestMethod]
  public void TestMethod1()
  {
    // This method belongs to project A and calls Grasshopper.dll while RhinoCore is being used.
    Tenrec.Utils.RunTenrecGroup(@"whatever gh filepath", groupInstanceID);
  }

I got this exception: System.IO.FileNotFoundException: Could not load file or assembly 'Grasshopper, Version=7.6.21127.19000, Culture=neutral, PublicKeyToken=dda4f5ec2cd80803' or one of its dependencies. The system cannot find the file specified.

For other side, the AppDomain.CurrentDomain.AssemblyResolve, as you can see in https://github.com/DanielAbalde/Tenrec/blob/251faef2a3757a7d4bb07afff47feb30d4193873/Headless.cs#L44 is referencing the versions of Rhino/GH located in RhinoInside.Resolver.RhinoSystemDirectory, which are 7.7.something my current installation.

I have tried things that have broken everything and I have finally got it back to working as before so I really need your help here.

Thank you.

sbaer commented 3 years ago

Are all of the assemblies set to copy-local=false? You don't want RhinoCommon or Grasshopper DLLs ending up in your bin directory.

DanielAbalde commented 3 years ago

Thanks for the reply @sbaer. I was aware of this issue and at some point I set them back to true to test, but I have reassured myself again by setting them all to false and the error is still the same.

image

sbaer commented 3 years ago

I would recommend against adding your own assembly resolver as that is supposed to be handled by RhinoInside https://github.com/mcneel/rhino.inside/blob/master/DotNet/RhinoInside/Resolver.cs#L16

Testing frameworks are always tricky to work with as they like to do things like use separate thread for tests and app domains. I don't know if that is the case here. Can you run any of the other RhinoInside examples at https://github.com/mcneel/rhino-developer-samples/tree/7/rhino.inside/dotnet

DanielAbalde commented 3 years ago

I compile RhinoInside including the Grasshopper folder in the AssemblyResolver like this:

https://github.com/DanielAbalde/rhino.inside/blob/e936d97f48665e0036b89866e3126808ad534aca/DotNet/RhinoInside/Resolver.cs#L45-L60

and calling RhinoInside.Resolver.Initialize() inside project B/secondary test host, has fixed the problem. I can keep one static instance of RhinoCore and I hope that it will be problem free.