在C#在运行时加载DLL在C#在运行时加载DLL(Loading DLLs at runtime i

2019-05-08 18:26发布

我试图找出你怎么能去在运行C#应用程序中导入和使用.dll文件。 使用Assembly.LoadFile()我设法让我的程序加载的dll(这部分是绝对的工作,因为我能够得到与的toString类的名称()),但我无法使用“输出”从我的控制台应用程序内的方法。 我编译.dll文件,然后将其移动到我的控制台的项目。 有没有的CreateInstance之间的一个额外的步骤,然后能够使用的方法?

这是我的DLL类:

namespace DLL
{
    using System;

    public class Class1
    {
        public void Output(string s)
        {
            Console.WriteLine(s);
        }
    }
}

这里是我想要加载DLL的应用程序

namespace ConsoleApplication1
{
    using System;
    using System.Reflection;

    class Program
    {
        static void Main(string[] args)
        {
            var DLL = Assembly.LoadFile(@"C:\visual studio 2012\Projects\ConsoleApplication1\ConsoleApplication1\DLL.dll");

            foreach(Type type in DLL.GetExportedTypes())
            {
                var c = Activator.CreateInstance(type);
                c.Output(@"Hello");
            }

            Console.ReadLine();
        }
    }
}

Answer 1:

会员必须是在编译时解析直接从C#调用。 否则,您必须使用反射或动态对象。

反射

namespace ConsoleApplication1
{
    using System;
    using System.Reflection;

    class Program
    {
        static void Main(string[] args)
        {
            var DLL = Assembly.LoadFile(@"C:\visual studio 2012\Projects\ConsoleApplication1\ConsoleApplication1\DLL.dll");

            foreach(Type type in DLL.GetExportedTypes())
            {
                var c = Activator.CreateInstance(type);
                type.InvokeMember("Output", BindingFlags.InvokeMethod, null, c, new object[] {@"Hello"});
            }

            Console.ReadLine();
        }
    }
}

动态(.NET 4.0)

namespace ConsoleApplication1
{
    using System;
    using System.Reflection;

    class Program
    {
        static void Main(string[] args)
        {
            var DLL = Assembly.LoadFile(@"C:\visual studio 2012\Projects\ConsoleApplication1\ConsoleApplication1\DLL.dll");

            foreach(Type type in DLL.GetExportedTypes())
            {
                dynamic c = Activator.CreateInstance(type);
                c.Output(@"Hello");
            }

            Console.ReadLine();
        }
    }
}


Answer 2:

现在,你创建的组件定义的每个类型的实例。 你只需要创建的单一实例Class1 ,以调用方法:

class Program
{
    static void Main(string[] args)
    {
        var DLL = Assembly.LoadFile(@"C:\visual studio 2012\Projects\ConsoleApplication1\ConsoleApplication1\DLL.dll");

        var theType = DLL.GetType("DLL.Class1");
        var c = Activator.CreateInstance(theType);
        var method = theType.GetMethod("Output");
        method.Invoke(c, new object[]{@"Hello"});

        Console.ReadLine();
    }
}


Answer 3:

你需要创建一个暴露的类型的实例Output方法:

static void Main(string[] args)
    {
        var DLL = Assembly.LoadFile(@"C:\visual studio 2012\Projects\ConsoleApplication1\ConsoleApplication1\DLL.dll");

        var class1Type = DLL.GetType("DLL.Class1");

        //Now you can use reflection or dynamic to call the method. I will show you the dynamic way

        dynamic c = Activator.CreateInstance(class1Type);
        c.Output(@"Hello");

        Console.ReadLine();
     }


Answer 4:

Activator.CreateInstance()返回一个对象,其不具有的输出方法。

它看起来像你来自动态编程语言? C#是definetly不说,什么你正在尝试做的将是困难的。

既然你是从一个特定的位置加载特定DLL,也许你只是想将其添加为您的控制台应用程序的参考?

如果你绝对要加载通过装配Assembly.Load ,你将不得不通过反射去呼吁所有成员c

type.GetMethod("Output").Invoke(c, null); 应该这样做。



Answer 5:

这不是那么困难。

您可以检查加载的对象可用的功能,如果你发现你的名字要找的人,那么窥探其预期PARMS,如果有的话。 如果这是你想找到的呼叫,然后使用MethodInfo对象的Invoke方法调用它。

另一种选择是简单地建立自己的外部对象的接口,并且加载的对象映射到该接口。 如果成功的话,本地调用该函数。

这是非常简单的东西。



文章来源: Loading DLLs at runtime in C#