Reputation: 95
I have two folders, one folder with files and the other one with DLL files, I can not know which or how many DLLs there is inside the DLL files directory (modular use). Inside every DLL file there is a function that gets FileInfo as parameter. How could I run all the functions in the DLLs on each file from the files directory?
for example, one of the DLL files:
using System;
using System.IO;
namespace DLLTest
{
public class DLLTestClass
{
public bool DLLTestFunction(FileInfo file)
{
return file.Exists;
}
}
}
Main:
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?
}
Thanks a lot.
Upvotes: 3
Views: 524
Reputation: 9679
Niels proposed a very good solution, with a clear interface. If you don't want to create interface, or if you cann't you could iterate all types and methods to find a known signature:
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 });
}
}
}
for this you do need that all classes have a parameterless constructor to instanciate it. As a parameter of Invoke
method you give your fileInfo object.
Upvotes: 2
Reputation: 1631
C# is static typed language, so if you want to call a specific function from many assemblies, the first step is to define one project with an interface for such a function.
You have to create one project (called ModuleInterface or anything else) with one interface :
public interface IDllTest
{
bool DLLTestFunction(FileInfo file);
}
Then all your Dll projects must have at least one classe which implements this interface :
public class DLLTestClass : IDllTest
{
public bool DLLTestFunction(FileInfo file)
{
return file.Exists;
}
}
Note the implementation of IDllTest above (you have to add a reference to project ModuleInterface).
Finally, in your main project, you have to load all your assemblies from a directory :
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);
}
It probably need some adjustments, because i don't have test it ! However I'm sure that it's the steps to follow.
Reference (in french) : http://www.lab.csblo.fr/implementer-un-systeme-de-plugin-framework-net-c/
I hope my English is understandable, feel free to correct me.
Upvotes: 2
Reputation: 822
You will have to load the assemblies dynamically find the function in it and call it. All steps are described here
Upvotes: 0