3

我试图找到一种方法,在我的应用程序已经启动后,我可以从 .NET DLL 执行代码。我在下面包含了一些伪代码,可能会尝试解释我正在尝试做的事情。我知道这可能比我想象的要复杂得多。

ClassLibrary myLibrary = new ClassLibrary("C:\\Users\\Admin\\Desktop\\myTestLibrary.dll");
myLibrary.executeMethod("showMessageMethod", arg1, arg2, arg3...);

这就是我想要做的,尽管我知道它可能比这复杂得多!

我还想明确表示,我确实理解您要在项目等中引用该库……但我的项目要求我不要这样做。

提前致谢!

4

5 回答 5

13

您需要从磁盘加载程序集,如下所示:

Assembly myLibrary = System.Reflection.Assembly
    .LoadFile("C:\\Users\\Admin\\Desktop\\myTestLibrary.dll");

之后,您将需要使用反射获取正确的类型并调用正确的方法。当您要调用的类实现在启动时引用的程序集中定义的接口时,这将是最方便的:

Type myClass = (
    from type in myLibrary.GetExportedTypes()
    where typeof(IMyInterface).IsAssignableFrom(type)
    select type)
    .Single();

var instance = (IMyInterface)Activator.CreateInstance(myClass);

instance.executeMethod("showMessageMethod", arg1, arg2, arg3...);
于 2012-10-04T08:34:08.370 回答
3

我希望下面的代码示例有所帮助。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;

namespace zielonka.co.uk.stackoverflow.examples.Reflection
{
    class Program
    {
        static void Main(string[] args)
        {

            // dynamically load assembly from file Test.dll
            Assembly testAssembly = Assembly.LoadFile(@"c:\Test.dll");


            // get type of class Calculator from just loaded assembly
            Type calcType = testAssembly.GetType("Test.Calculator");


            // create instance of class Calculator
            object calcInstance = Activator.CreateInstance(calcType);

            // get info about property: public double Number
            PropertyInfo numberPropertyInfo = calcType.GetProperty("Number");

            // get value of property: public double Number
            double value = (double)numberPropertyInfo.GetValue(calcInstance, null);

            // set value of property: public double Number
            numberPropertyInfo.SetValue(calcInstance, 10.0, null);

            // get info about static property: public static double Pi
            PropertyInfo piPropertyInfo = calcType.GetProperty("Pi");

            // get value of static property: public static double Pi
            double piValue = (double)piPropertyInfo.GetValue(null, null);

            // invoke public instance method: public void Clear()
            calcType.InvokeMember("Clear",
                BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Public,
                null, calcInstance, null);

            // invoke private instance method: private void DoClear()
            calcType.InvokeMember("DoClear",
                BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.NonPublic,
                null, calcInstance, null);

            // invoke public instance method: public double Add(double number)
            double value = (double)calcType.InvokeMember("Add",
                BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Public,
                null, calcInstance, new object[] { 20.0 });

            // invoke public static method: public static double GetPi()
            double piValue = (double)calcType.InvokeMember("GetPi",
                BindingFlags.InvokeMethod | BindingFlags.Static | BindingFlags.Public,
                null, null, null);


            // get value of private field: private double _number
            double value = (double)calcType.InvokeMember("_number",
                BindingFlags.GetField | BindingFlags.Instance | BindingFlags.NonPublic,
                null, calcInstance, null);

        }
    }
}
于 2012-10-04T08:44:49.707 回答
1

虽然您可以按照 Steven 的回答中的详细说明加载程序集,但还有另一种可能性。

在解决方案中添加对程序集的引用,但不将程序集部署为解决方案的一部分。这意味着您不必使用反射,而是使用 AppDomain.AssemblyResolve 事件。

您的需求尚不清楚,但本质上这是一种注入 dll 的方式。

例如,假设您有 dll 来为您支持的每个后端实现数据库操作。

当您的代码尝试查找程序集时,它会在通常的位置查找,如果尚未加载且无法找到,则会触发 AssmemblyResolve 事件,并在其中根据某些配置选项从某个可访问的位置动态加载它.

可访问的位置,可以是一个 url,一个完全不同的路径,甚至是网络路径。显然不是这个例子,但它甚至可以是数据库中的一个 blob。

于 2012-10-04T08:59:47.110 回答
0

第一个解决方案是使用:

Assembly asm = Assembly.LoadFrom(path);

第二个是:MEF

于 2012-10-04T08:34:56.357 回答
0

您正在寻找的可能是一种在运行时动态加载程序集的方法。

看这个视频:http ://www.youtube.com/watch?v=WBoA36pwxJE

于 2012-10-04T08:35:45.110 回答