I'm having problems with a System.MissingMethodException "Method not found", although immediately before the line causing the exception I look at the currently loaded assemblies using reflection and can see that the method exists.
This is the text from the exception:
System.MissingMethodException
HResult=0x80131513
Message=Methode nicht gefunden: "Void ConstraintSolverExpressions.CSEObjectFactory..ctor(Google.OrTools.ConstraintSolver.Solver, Int32)".
Source=CSP_E04B_8_0_2021-06-24_11_00initial_temp
StackTrace:
at CSP_E04B_8_0.CConstraintSolverExpressions.createCSEIntVars() in c:\Users\hamkchr\AppData\Local\Temp\GoogleORModelBuilder_1117304b-283d-41c2-a432-6bb39575937f\CSP_E04B_8_0_2021-06-24_11_00.cs:line 45155
at CSP_E04B_8_0.CConstraintSolverExpressions..ctor(Solver s_, CSolverIntVars fc_) in c:\Users\hamkchr\AppData\Local\Temp\GoogleORModelBuilder_1117304b-283d-41c2-a432-6bb39575937f\CSP_E04B_8_0_2021-06-24_11_00.cs:line 44708
The code line causing the exception:
cseFactory = new ConstraintSolverExpressions.CSEObjectFactory(solver, logLevel);
To investigate the problem, I made a method to retrieve information about the loaded assemblies
public static string getAssemblyInfo(string name)
{
var sb = new StringBuilder();
Assembly[] loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies();
foreach (Assembly assem in loadedAssemblies)
{
if (assem.FullName.Contains(name))
{
sb.AppendLine(assem.FullName);
sb.AppendLine(string.Format("Dynamic: {0}", assem.IsDynamic));
if (!assem.IsDynamic) sb.AppendLine(string.Format("Location: {0}", assem.Location));
foreach (TypeInfo typeInfo in assem.DefinedTypes)
{
sb.Append("Type: ");
sb.AppendLine(typeInfo.FullName);
foreach (ConstructorInfo constructorInfo in typeInfo.GetConstructors())
{
sb.Append("Constructor ");
sb.AppendLine(constructorInfo.ToString());
}
}
}
}
return sb.ToString();
}
As a test, I call the method just before the exception occurs and output the information to a log.
There I can see
ConstraintSolverExpressions, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
Dynamic: False
Location: C:\Users\hamkchr\AppData\Local\Temp\51dd0c11-cb06-4f45-8baf-8ca462e47b2b\51dd0c11-cb06-4f45-8baf-8ca462e47b2b\assembly\dl3\04dc249d\bbfb2faa_3268d701\ConstraintSolverExpressions.dll
... some types omitted here ...
Type: ConstraintSolverExpressions.CSEObjectFactory
Constructor Void .ctor(Google.OrTools.ConstraintSolver.Solver, Int32)
So I can see that the loaded assembly ConstraintSolverExpressions has a constructor for the type with the exact signature needed, ConstraintSolverExpressions.CSEObjectFactory Constructor Void .ctor(Google.OrTools.ConstraintSolver.Solver, Int32), but the exception is still being thrown.
Does anyone have an idea why the constructor isn't being found and an exception is thrown?
Perhaps relevant here:
The exception is thrown in a method that was dynamically generated using Code DOM, saved as c# source code, compiled to a dll, then explicitly loaded and executed. In the CompilerParameters.ReferencedAssemblies for the compilation, the exact same ConstraintSolverExpressions.dll (same file location) was specified as for the currently loaded assembly.
As already mentioned in the comments, the problem arises when an assembly with a base class used in the dynamically created assembly was loaded twice from two different locations. The dll was identical in both locations (binary comparison shows no differences), but resolving this problem led the application to find the method in the assembly ConstraintSolverExpressions. I still don't understand why having a different assembly loaded twice leads to a problem with this one, but things are working now.
My solution is to strictly prevent loading any assemblies already present a second time, in particular when it would be from a different location.