在带有命名空间的 asp.net 项目中的另一个 DLL 中调用方法

Invoke Method inside another DLL in a asp.net project WITH a namespace

我们有一个 asp.net 4.7 项目,我们正在尝试调用另一个 dll 文件中的方法(来自 /Bin 中的一个 dll 文件)

项目结构如下:

我们的主要项目

编译项目时所有文件会自动复制到Asp.net项目文件夹/Bin

Image

在我们的库项目中,我们有调用方法:

    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;
    }

并且在框架项目中我们有调用我们想要调用的方法的函数:

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

最后 WA.Extension.Pages 我们有:

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

            }
        }
    }

但到目前为止它给我的只是

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

我仔细检查了参考资料,应该可以。

编辑:

在玩弄它并在此线程的帮助下,我得到了这个:

    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;
    }

添加的重要内容之一是绑定标志中的 asambly 名称和 Activator.CreateInstance(calledType)。

所以当我想调用方法时:

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

感谢您的帮助!

Init() 在您的示例中是一个实例(非静态)方法。您应该添加 BindingFlag.Instance 并提供 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;
} 

或者您可以将 Init() 方法标记为 static:

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

并仅添加一个 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;
}

之后尝试调试 Init() 方法。我怀疑 HttpContext.Current 可能是 null。在这种情况下,您可以将 HttpContext 实例作为参数传递给 through InvokeMember:

public static void Init(HttpContext ctx)
{
    ctx.Response.Write("hello from 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.Static,
                    null,
                    null,
                    new object[] { HttpContext.Current });

    return s;
}

希望对您有所帮助。