【问题标题】:C# use DLL functions dynamicallyC#动态使用DLL函数
【发布时间】:2016-12-18 18:25:23
【问题描述】:

我有两个文件夹,一个文件夹包含文件,另一个文件夹包含 DLL 文件,我不知道 DLL 文件目录中有哪些或多少个 DLL(模块化使用)。 在每个 DLL 文件中都有一个获取 FileInfo 作为参数的函数。 如何在文件目录中的每个文件上运行 DLL 中的所有函数?

例如,其中一个 DLL 文件:

using System;
using System.IO;
namespace DLLTest
{
    public class DLLTestClass
    {
        public bool DLLTestFunction(FileInfo file)
        {
            return file.Exists;
        }
    }
}

主要:

DirectoryInfo filesDir = new DirectoryInfo(path_to_files_Directory);
DirectoryInfo dllsDir = new DirectoryInfo(path_to_dlls_Directory);

foreach(FileInfo file in filesDir.getFiles())
{
    //How do I run each one of the dll funtions on each one of the files?
}

非常感谢。

【问题讨论】:

    标签: c# file dll modularity


    【解决方案1】:

    C# 是静态类型语言,因此如果您想从多个程序集中调用特定函数,第一步是定义一个项目,并为此类函数定义一个接口。

    你必须用一个接口创建一个项目(称为ModuleInterface或其他任何东西):

    public interface IDllTest
    {
        bool DLLTestFunction(FileInfo file);
    }
    

    那么你所有的 Dll 项目必须至少有一个实现这个接口的类:

    public class DLLTestClass : IDllTest
    {
        public bool DLLTestFunction(FileInfo file)
        {
            return file.Exists;
        }
    }
    

    注意上面 IDllTest 的实现(您必须添加对项目 ModuleInterface 的引用)。

    最后,在您的主项目中,您必须从一个目录加载所有程序集:

    DirectoryInfo dllsDir = new DirectoryInfo(path_to_dlls_Directory);
    
    foreach(FileInfo file in dllsDir.getFiles())
    {
        //Load the assembly
        Assembly assembly = Assembly.LoadFile (file.FullName);
    
        //Get class which implements the interface IDllTest
        Type modules = assembly.GetTypes ().SingleOrDefault(x => x.GetInterfaces().Contains(typeof(IDllTest)));
        //Instanciate
        IDllTest module = (IDllTest)Activator.CreateInstance (modules);
    
        //Call DllTestFunction (you have to define anyFileInfo)
        module.DLLTestFunction(anyFileInfo);
    }
    

    它可能需要一些调整,因为我没有测试它! 但是我确信这是要遵循的步骤。

    参考(法语):http://www.lab.csblo.fr/implementer-un-systeme-de-plugin-framework-net-c/

    我希望我的英语是可以理解的,请随时纠正我。

    【讨论】:

      【解决方案2】:

      Niels 提出了一个非常好的解决方案,界面清晰。如果您不想创建接口,或者如果您不想创建接口,则可以迭代所有类型和方法以找到已知签名:

      var definedTypes = Assembly.LoadFile("file").DefinedTypes;
      foreach(var t in definedTypes)
      {
          foreach(var m in t.GetMethods())
          {
              var parameters = m.GetParameters();
              if (parameters.Length ==1 && parameters[0].ParameterType == typeof(FileInfo))
              {
                  var instanse = Activator.CreateInstance(t);
                  m.Invoke(instanse, new[] { fileInfo });
               }
           }
      }
      

      为此,您确实需要所有类都有一个无参数构造函数来实例化它。作为Invoke 方法的参数,您将给出您的fileInfo 对象。

      【讨论】:

      • 也很有趣:-)
      【解决方案3】:

      您必须动态加载程序集并在其中找到函数并调用它。所有步骤都描述here

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-08-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-01-31
        • 1970-01-01
        • 2011-09-06
        相关资源
        最近更新 更多