C# use DLL functions dynamically

490 views Asked by At

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.

3

There are 3 answers

0
csblo On BEST ANSWER

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.

1
Maksim Simkin On

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.

0
H.G. Sandhagen On

You will have to load the assemblies dynamically find the function in it and call it. All steps are described here