0

I'm trying to call from another assembly a base class static method from it's derived class dynamically, using the following code:

Assembly executingAssembly = Assembly.GetExecutingAssembly();

Assembly objectAssembly = 
    Assembly.Load(executingAssembly.GetReferencedAssemblies().
    Where(a => a.Name == "WebDelightBLL").FirstOrDefault());

Type myType = objectAssembly.GetType("WebDelightBLL.Ingredient");

MethodInfo myMethod = myType.GetMethod("GetAll", BindingFlags.Public | BindingFlags.Static);

object myInstance = Activator.CreateInstance(myType);

dgvResultsRES.DataSource = myMethod.Invoke(myInstance, null);

Code in the Dll as following:

public class BaseClass<DerivedClass>
{
    public static Type MyType()
    {
        return typeof(DerivedClass);
    }
    public static string Prefix()
    {
        return "Sp" + MyType().Name;
    }
    public static DataTable GetAll()
    {
        try
        {
            DataTable dt = GetSP(Connection.connectionString(),
              Prefix() + "GetAll", 5);
            return dt;
        }
        catch (Exception)
        {
            throw;
        }
    }
}
public class Ingredient : BaseClass<Ingredient>
{
    public string SayHello()
    {
        return "Hello, World!"; //Just to exemplify a point
    }
}

But I always get "Object reference not set to an instance of an object"

If I try to call 'SayHello()' for instance I get no error.

Is this even possible?

Update:

By adding BindingFlags.FlattenHierarchy as indicated by Creep it worked like a charm. Working code as follows:

        Type myType = objectAssembly.GetType("WebDelightBLL.Ingredient");

        MethodInfo myMethod = myType.GetMethod("GetAll", BindingFlags.Public 
            | BindingFlags.Static | BindingFlags.FlattenHierarchy);

        //object myInstance = Activator.CreateInstance(myType); <-- not needed.

        dgvResultsRES.DataSource = myMethod.Invoke(null, null);
João Sequeira
  • 157
  • 3
  • 12
  • You may want to create an answer to your question, and select this as your solution :) –  Jan 05 '17 at 13:23
  • Wouldn't it be fairer if @Creep did the answer and I picked it as solution? This is my first post s I'd like to be as polite as possible to Creep, saved a lot of future headaches... – João Sequeira Jan 05 '17 at 13:48
  • My bad - I did not realize that Creep's answer is essentially the solution (with little adjustments in your actual code base). So, yep, I suggest to pick his answer as the solution. –  Jan 05 '17 at 15:03

2 Answers2

1

Since your method is static in your base class, it does not belong to its child.
The following code will work:

Type myType = objectAssembly.GetType("WebDelightBLL.BaseClass");
MethodInfo myMethod = myType.GetMethod("GetAll", BindingFlags.Public | BindingFlags.Static);
myMethod.Invoke(null, null);
Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
Creep
  • 300
  • 3
  • 12
  • The problem here is that it should be called from the derived class in order to maintain the dynamics of the code. – João Sequeira Jan 05 '17 at 13:04
  • 1
    Just a guess but if you work on the child class and add the flag | BindingFlags.FlattenHierarchy `Type myType = objectAssembly.GetType("WebDelightBLL.Ingredient"); MethodInfo myMethod = myType.GetMethod("GetAll", BindingFlags.Public | BindingFlags.Static| BindingFlags.FlattenHierarchy); myMethod.Invoke(null, null);` – Creep Jan 05 '17 at 13:06
  • 1
    Brilliant! ;) FlatterHierarchy did it... – João Sequeira Jan 05 '17 at 13:11
1

You're trying to invoke static method so you cannot specify instance of the object ( to get rid of "Object reference not set to an instance of an object" error ). And since this method doesn't have any parameters you can just create an empty parameter array

MethodInfo myMethod = myType.GetMethod("GetAll", BindingFlags.Public | BindingFlags.Static);
// dont need this
//object myInstance = Activator.CreateInstance(myType);

//dgvResultsRES.DataSource = myMethod.Invoke(myInstance, null);
dgvResultsRES.DataSource = myMethod.Invoke(null, new object[0]);
mrogal.ski
  • 5,828
  • 1
  • 21
  • 30