2

I'm creating an assembly via reflection. When I try to run my application I get an MissingMethodExeption on :

        // public static bool berekenQueens(int Row, int N, bool[,] bord)
        objType.InvokeMember("berekenQueens",
            BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Static,
            null, instance, null);

        // private static bool bordValidatie(int currentRow, int currentCol, bool[,] currentBord, int N)
        objType.InvokeMember("bordValidatie",
            BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Static,
            null, instance, null);     

My code (When clicked on the menuItem I want to create an assembly and load the classes)

    private void MenuItem_Click(object sender, RoutedEventArgs e)
    {
        // Create an assembly object to load our classes
        string path = System.Environment.CurrentDirectory + "\\NQueens.dll";
        Assembly ass = Assembly.LoadFile(path);
        Console.WriteLine(path);

        Type objType = ass.GetType("NQueens.NQueen");

        // Create an instace of NQueens.NQueen
        var instance = Activator.CreateInstance(objType);

        // public static bool berekenQueens(int Row, int N, bool[,] bord)
        objType.InvokeMember("berekenQueens",
            BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Static,
            null, instance, null);

        // private static bool bordValidatie(int currentRow, int currentCol, bool[,] currentBord, int N)
        objType.InvokeMember("bordValidatie",
            BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Static,
            null, instance, null);     
    }

The methods I want to load come from my project NQueens.

public class NQueen
{
public static bool berekenQueens(int Row, int N, bool[,] bord)
{
   if (Row >= N) return true; 
   for (int Col = 0; Col < N; Col++)
   {
       //Q toevoegen
       bord[Row, Col] = true;
       //Q + Q volgende Row  controleren
       if (bordValidatie(Row, Col, bord, N) && berekenQueens(Row + 1, N, bord))
       {
           return true;
       }
       //Q verwijderen indien niet door controle
       bord[Row, Col] = false;
   }
   return false;
}


private static bool bordValidatie(int currentRow, int currentCol, bool[,] currentBord, int N)
{
   int colstep = 1;
   for (int i = currentRow - 1; i >= 0; i--)
   {
       //rechte lijn 
       if (currentBord[i, currentCol])
           return false;
       //linker diagonaal
       if (currentCol - colstep >= 0)
       {
           if (currentBord[i, currentCol - colstep])
               return false;
       }
       //rechter diagonaal
       if (currentCol + colstep < N)
       {
           if (currentBord[i, currentCol + colstep])
               return false;
       }
       colstep += 1;
   }
   return true;
}
}

Can anyone help me with this?

Austin Salonen
  • 49,173
  • 15
  • 109
  • 139
user1951083
  • 261
  • 1
  • 5
  • 20
  • Have you tried the failing line without `BindingFlags.Instance` since it's a static method? – Austin Salonen Jan 26 '13 at 15:13
  • Yes, same error. Probably something wrong with my arguments from berekenQueens and bordValidatie methods. – user1951083 Jan 26 '13 at 15:18
  • is this Assembly truly being created or does it already exist.. I am wondering if you are torn between `Assembly.LoadFrom` vs `Assembly.LoadFile` – MethodMan Jan 26 '13 at 15:23
  • 1
    Improve your code by using Type.GetMethod + MethodInfo.Invoke. You'll find out quicker that you are trying to use the wrong method overload. – Hans Passant Jan 26 '13 at 15:28
  • @HansPassant I've tried this to check. MethodInfo[] methodInfos = this.GetType().GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static); foreach (MethodInfo methodInfo in methodInfos) { Console.WriteLine(methodInfo.Name); } Nothing comes in my console. – user1951083 Jan 26 '13 at 15:50

2 Answers2

3

The binder uses the arguments as well to find a suitable method. You have no method void berekenQueens() therefor calling InvokeMember with null as the last parameter (the arguments array) will not give a matching Method. You don't really need the instance (because the method is static) so you leave it null if you wish.

      Type objType = ass.GetType("NQueens.NQueen");
      // Create an instace of NQueens.NQueen
      var instance = Activator.CreateInstance(objType);

    var result = objType.InvokeMember("berekenQueens", 
    BindingFlags.InvokeMethod | 
    BindingFlags.Static | 
    BindingFlags.Public,
      null, 
      instance, 
    new object[] {   1, /* Row */ 
                     1, /* N */
                     new bool[,] { {true,false} } /* bord */
                    });
rene
  • 41,474
  • 78
  • 114
  • 152
  • Because I'm using reflection I may not add a reference (NQueen) so this is not an option? – user1951083 Jan 26 '13 at 15:45
  • I added the lines you used to get hold of the type and create the instance, so in your scenario this still works... – rene Jan 26 '13 at 15:48
  • Thank you, no MissingMethodException anymore! Do you have any idea how I can show my NQueens project in my current project when clicked on the menuItem? I think I'm almost there, loading the NQueens.dll, invoking the same methods as my NQueens class, but how can I show in my window now? – user1951083 Jan 26 '13 at 16:03
  • 1
    Ask a new question about that but var frm = new Form(); frm.Show(); might get you started... – rene Jan 26 '13 at 16:12
1

use BindingFlags.NonPublic in place of BindingFlags.Instance for method bordValidatie as it is a private method.

Kiran1016
  • 914
  • 4
  • 14
  • Thanks but still the same error. Method bordValidatie has 5 arguments, so I think the Invoke needs more arguments? – user1951083 Jan 26 '13 at 15:24
  • 1
    check this link it shows how to send parametes to method using reflection.http://stackoverflow.com/questions/135443/how-do-i-use-reflection-to-invoke-a-private-method-in-c – Kiran1016 Jan 26 '13 at 15:27