返回动态库上类的实例

本文关键字:实例 动态 返回 | 更新日期: 2023-09-27 17:57:31

我学习了如何动态加载dll到程序中。我有关于图书馆的测试课:

public class Class1
{
    public int Number { get; set; }
    public string GetWorld()
    {
        return "Hello world!";
    }
}

在我的程序代码中,动态加载这个库,函数TestLibraryMethod从库中返回Class的实例。那么它是如何写正确的呢?

class Program
{
    static void Main(string[] args)
    {
        try
        {
            var DLL = Assembly.LoadFile(@"C:'TestLibrary.dll");
            var reportType = DLL.GetTypes().ToList().Where(t => t.Name == "Class1").Single();
            var instance = Activator.CreateInstance(reportType);
            Class1 test=(call TestLibraryMethod()?)
            Console.WriteLine(test.Number);  
            Console.WriteLine(test.GetWorld());                              
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
        }
    }
    public static Class1 TestLibraryMethod()
    {
        Class1 test = new Class1();
        test.Number = 5;
        return test;
    }
}

返回动态库上类的实例

由于该类型在流程的编译阶段是未知的,因此需要使用反射来访问它。您可以在MSDN上找到该主题的介绍。

例如,以您的示例为例,要读取属性并调用方法,您将编写以下内容:

PropertyInfo NumberProp = reportType.GetProperty("Number");
Console.WriteLine(NumberProp.GetValue(instance));
MethodInfo GetWorldMethod = reportType.GetMethod("GetWorld");
Console.WriteLine(GetWorldMethod.Invoke(instance, null));

以这种方式使用反射并不是很有趣。我怀疑您最好在宿主程序集和动态加载程序集都使用的程序集中定义一个接口。在动态加载的程序集中,您将定义一个实现该类型的类,并提供一个创建和返回新实例的方法。通过这种方式,您可以在编译时绑定到类型。

@David所指的是,你通常不能这样做。然而,如果你仍然想要这样的功能,你需要考虑接口(或合同)来完成这项工作。

假设在组件A中,您定义了接口:

public interface IRunnable
{
   void Run();
}

在程序集B中,您有具体的实现。所以这个程序集引用了A。所以程序集中的一个类实现了IRunnable。

在前端,即目标程序集(可能是桌面应用程序、web应用程序或任何应用程序)中,添加对程序集a的引用。程序集B是动态加载的。该特定类型将像上面所做的那样实例化,并将该实例提供给一个IRunnable变量。

因此,在您的情况下,实例化代码将是:

var instance = (IRunnable) Activator.CreateInstance(reportType);
instance.Run();

这是推荐的方法。