dimanche 26 juillet 2020

MethodInfo.Invoke with custom Class List as parameter

I'm actually writing a simple application that calls functions of an external DLL's based on a command line. First I do have a parameter Class that holds all parameters after parsing from command line:

public class ParserFunctionParameter
{
    string parameterName = "";
    string parameterValue = "";

    public ParserFunctionParameter(string parameterName, string parameterValue)
    {
        this.parameterName = parameterName;
        this.parameterValue = parameterValue;
    }
}

Then I wrote a FunctionLoader Class which basically contains a list of all pre registered DLL's. A single function within this Class looks like this:

public class Function
{
    private Assembly assemblyReference;
    private string functionName;
   
    public Function(Assembly assembly)
    {
        this.assemblyReference = assembly;
        AssemblyName an = assembly.GetName();
        Type type = assembly.GetType(an.Name + ".Class1");
        object o = Activator.CreateInstance(type);
        MethodInfo mi = type.GetMethod("GetFunctionName");
        this.functionName = (string)mi.Invoke(o, null);
    }

    public double[] CallFunction(List<ParserFunctionParameter> parameters)
    {
        AssemblyName an = assemblyReference.GetName();
        Type type = assemblyReference.GetType(an.Name + ".Class1");
        object dllClassObject = Activator.CreateInstance(type);
        MethodInfo mi = type.GetMethod(functionName);
        object[] objParamArray = { parameters };
        return (double[]) mi.Invoke(dllClassObject, objParamArray);
    }
}

So far, this is the application that makes use of the DLL. The DLL itself, looks like this:

public class Class1
{
    public string GetFunctionName()
    {
        return "importcsv";
    }

    public double[] importcsv(List<ParserFunctionParameter> parameters)
    {
        // do some stuff depending on parameters 
    }
}

Let's assume I use it this way, after I've compiled the DLL to ImportCSV.dll:

class Program
{
    static void Main(string[] args)
    {
        List<ParserFunctionParameter> par = new List<ParserFunctionParameter>();
        par.Add("file", "C:\test.csv");
        par.Add("skiplines", "1");

        Function func = new Function(Assembly.LoadFile("ImportCSV.dll",)
        double[] result = func.CallFunction(par);
    }
}

The (not very helpful) exception:

System.ArgumentException: 'Object of type 'System.Collections.Generic.List`1[BML.Parser.ParserFunctionParameter]' cannot be converted to type 'System.Collections.Generic.List`1[BML.Parser.ParserFunctionParameter]'.'

How can I pass the List of ParserFunctionParameter ? I've tried simple 'build in' types like string. This works pretty straight forward. But with this 'custom' type this isn't working.

Since this is just a coding for fun project and to check feasibility of a simple plugin interface, I can provide the complete code, if needed.

Edit: Thaks for the comment on the reserved keyword, but that's not causing the exception. This was just an example of calling. I'm sorry for that -> Corrected it.

Thank you.





Aucun commentaire:

Enregistrer un commentaire