3

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.

FinFon
  • 85
  • 1
  • 2
  • 8

3 Answers3

2

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.

csblo
  • 1,571
  • 13
  • 20
2

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.

Maksim Simkin
  • 9,561
  • 4
  • 36
  • 49
0

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

Community
  • 1
  • 1
H.G. Sandhagen
  • 772
  • 6
  • 13