lundi 11 avril 2016

C# Reflection "Cannot perform runtime binding on a null reference"

I'm running into a problem while dynamically compiling classes. There are 4 parts which take part in this, first the Interface:

public interface IReaderPlugin
{
    string getPluginName();
    List<Tuple<string,string,Type>> getParamWithType();
    void setParams(Dictionary<string, object> param);
    List<Tuple<string,string,int>> Execute();
}

Pretty straightforward, next up is its implementation(plaintext):

public class TestPlugin: IReaderPlugin
{
    static void Main()
    {
    }

    public string getPluginName()
    {
        return "eeh";
    }

    public List<Tuple<string,string,Type>> getParamWithType()
    {
        return null;
    }

    public void setParams(Dictionary<string, object> param)
    {

    }

    public List<Tuple<string,string,int>> Execute()
    {
        return null;
    }
}

Then the method that will compile the above text file into a .dll:

public dynamic Compile(String classCode, String mainClass, Object[] requiredAssemblies)
{
    CSharpCodeProvider provider = new CSharpCodeProvider(new Dictionary<string, string> 
      { 
         { "CompilerVersion", "v4.0" } 
      });

    CompilerParameters parameters = new CompilerParameters
    {
        GenerateExecutable = true,       // Create a dll
        GenerateInMemory = true,          // Create it in memory
        WarningLevel = 3,                 // Default warning level
        CompilerOptions = "/optimize",    // Optimize code
        TreatWarningsAsErrors = false     // Better be false to avoid break in warnings
    };

    foreach (var extraAsm in requiredAssemblies)
    {
        parameters.ReferencedAssemblies.Add(extraAsm as string);
    }

    CompilerResults results = provider.CompileAssemblyFromSource(parameters, classCode);

    if (results.Errors.Count != 0)
    {
        return "FAILED";
    }
    return results.CompiledAssembly.CreateInstance(mainClass); ;
}

And finally the 2 lines I use to test if the compiler succeeded:

        dynamic obj = compile.Compile("PATHTOFILE", "NAMESPACE.CLASSNAME", new object[] { "Plugins\\Reader\\IReader.dll" });
        obj.Execute();

To help the compiler, I even compiled the IReaderPlugin into a .dll and added it as extra reference (as you can see in the compile.Compile). I get no errors or warnings when compiling, however when calling any of the methods, I get the following error :

An unhandled exception of type 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' occurred in System.Core.dll
Additional information: Cannot perform runtime binding on a null reference





Aucun commentaire:

Enregistrer un commentaire