-2

We have an asp.net 4.7 project and we're trying to call a method in another dll file ( from one of the dll files inside /Bin )

This is how the project structure looks:

Our Main project

  • Sub project: Asp.net Project - hosted on a webserver
  • Another sub project called WA.Core.Framework
  • Another sub project called WA.Core.Libary
  • Another sub project callde WA.Extension.Pages

When compiling the project all the files will automatically be copied to the Asp.net project folder /Bin

Image

In our Library project we have the invoke method:

    public string InvokeString(string typeName, string methodName)
    {
        Type calledType = Type.GetType(typeName);

        String s = (String)calledType.InvokeMember(
                        methodName,
                        BindingFlags.InvokeMethod | BindingFlags.Public,
                        null,
                        null,
                        null);

        return s;
    }

And in the framework project we have the function that calls the method we want to call:

new Lib_Invoke().InvokeString("WA.Extension.Pages.Extension", "Init");

And last in our WA.Extension.Pages we have:

namespace WA.Extension.Pages
    {
        public class Extension
        {
            public void Init()
            {
                HttpContext.Current.Response.Write("hello from extension");

            }
        }
    }

But so far all it gives me is

System.NullReferenceException: Object reference not set to an instance of an object.

I have double checked the references and should work.

EDIT:

After playing around with it and with the help from this thread, I ended up with this:

    public string InvokeString(string assemblyName, string namespaceName, string typeName, string methodName)
    {
        Type calledType = Type.GetType(namespaceName + "." + typeName + "," + assemblyName);

        String s = (String)calledType.InvokeMember(
                        methodName,
                        BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance,
                        null,
                        Activator.CreateInstance(calledType),
                        null);
        return s;
    }

One of the important things that was added was the asambly name and Activator.CreateInstance(calledType) in the bindingflags.

So when I want to call the method:

new Lib_Invoke().InvokeString("WA.Extension.Pages", "WA.Extension.Pages", "Extension", "Init");

Thanks for your help!

ClausDK
  • 3
  • 3
  • Is the dll actually loaded, or is it just sitting int he directory? is it referenced, you need more informatiuon – TheGeneral Sep 02 '18 at 02:12
  • Updated the description a little. Hope it's better. Thanks. + Yeah, I'm able to use the method normally from an asp.net page or if I use the /App_Code. – ClausDK Sep 02 '18 at 02:26
  • 1
    Possible duplicate of [Type.GetType("namespace.a.b.ClassName") returns null](https://stackoverflow.com/questions/1825147/type-gettypenamespace-a-b-classname-returns-null) – Alejandro Sep 02 '18 at 02:36

1 Answers1

0

Init() is an instance(non-static) method in your example. You should add BindingFlag.Instance and provide target object of type Extension:

public static string InvokeString(string typeName, string methodName)
{
    Type calledType = Type.GetType(typeName);            

    String s = (String)calledType.InvokeMember(
                    methodName,
                    BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance,
                    null,
                    Activator.CreateInstance(calledType),
                    null);

    return s;
} 

Or you can mark Init() method as static:

public static void Init()
{
    HttpContext.Current.Response.Write("hello from extension");
}

and add just a BindingFlag.Static:

public static string InvokeString(string typeName, string methodName)
{
    Type calledType = Type.GetType(typeName);            

    String s = (String)calledType.InvokeMember(
                    methodName,
                    BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static,
                    null,
                    null,
                    null);

    return s;
}

After that try to debug the Init() method. I suspect that HttpContext.Current may be null. In this case you can pass HttpContext instance as argument to through InvokeMember:

public static void Init(HttpContext ctx)
{
    ctx.Response.Write("hello from extension");
}

and:

public static string InvokeString(string typeName, string methodName)
{
    Type calledType = Type.GetType(typeName);            

    String s = (String)calledType.InvokeMember(
                    methodName,
                    BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static,
                    null,
                    null,
                    new object[] { HttpContext.Current });

    return s;
}

Hope it helps.

KozhevnikovDmitry
  • 1,660
  • 12
  • 27
  • Thanks for your help. Turns out it was a combo of 2 tings. I changed code so it includes the asambly name after the , in the typeName. And the BindingFlags.Instance + Activator.CreateInstance(calledType) in the InvokeMember configuration – ClausDK Sep 02 '18 at 03:58