C#动态使用DLL函数
C# use DLL functions dynamically
我有两个文件夹,一个是文件文件夹,一个是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?
}
非常感谢。
您将不得不动态加载程序集,找到其中的函数并调用它。描述了所有步骤 here
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/
我希望我的英语是可以理解的,欢迎指正。
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 对象。
我有两个文件夹,一个是文件文件夹,一个是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?
}
非常感谢。
您将不得不动态加载程序集,找到其中的函数并调用它。描述了所有步骤 here
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/
我希望我的英语是可以理解的,欢迎指正。
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 对象。