jeudi 9 avril 2015

System.Reflection.TargetInvocationException: dynamically define constructor with parameters

We want to dynamically create a class, the constructor as below:



public JsRF1013Wrapper(ScriptEngine scriptEngine, string jsFileFullPath)
{
this.ScriptEngine = scriptEngine;
var jsFileContent = File.ReadAllText(jsFileFullPath);
this.ScriptEngine.Execute(jsFileContent);
}


we got the IL:



.method public hidebysig specialname rtspecialname
instance void .ctor(class [ClearScript]Microsoft.ClearScript.ScriptEngine scriptEngine,
string jsFileFullPath) cil managed
{
// Code size 37 (0x25)
.maxstack 2
.locals init ([0] string jsFileContent)
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: nop
IL_0007: nop
IL_0008: ldarg.0
IL_0009: ldarg.1
IL_000a: stfld class [ClearScript]Microsoft.ClearScript.ScriptEngine TotalTaxation.TaxformCalculationUnitTests.JsRF1013Wrapper::ScriptEngine
IL_000f: ldarg.2
IL_0010: call string [mscorlib]System.IO.File::ReadAllText(string)
IL_0015: stloc.0
IL_0016: ldarg.0
IL_0017: ldfld class [ClearScript]Microsoft.ClearScript.ScriptEngine TotalTaxation.TaxformCalculationUnitTests.JsRF1013Wrapper::ScriptEngine
IL_001c: ldloc.0
IL_001d: callvirt instance void [ClearScript]Microsoft.ClearScript.ScriptEngine::Execute(string)
IL_0022: nop
IL_0023: nop
IL_0024: ret
} // end of method JsRF1013Wrapper::.ctor


we wrote the emit code: ConstructorInfo objCtor = calculatorType.GetConstructor(new Type[] { typeof(ScriptEngine), typeof(string) });



Type[] ctorParams = new Type[] { typeof(ScriptEngine), typeof(string) };

ConstructorBuilder wrapperCtor = typeBuilder.DefineConstructor(
MethodAttributes.Public |
MethodAttributes.SpecialName |
MethodAttributes.RTSpecialName,
CallingConventions.Standard,
ctorParams);
ILGenerator ctorIL = wrapperCtor.GetILGenerator();

ctorIL.Emit(OpCodes.Ldarg_0);
ctorIL.Emit(OpCodes.Call, objCtor);
ctorIL.Emit(OpCodes.Nop);
ctorIL.Emit(OpCodes.Nop);
ctorIL.Emit(OpCodes.Ldarg_0);
ctorIL.Emit(OpCodes.Ldarg_1);
ctorIL.Emit(OpCodes.Stfld, scriptEngineField);
ctorIL.Emit(OpCodes.Ldarg_2);
ctorIL.Emit(OpCodes.Call, typeof(File).GetMethod("ReadAllText", new Type[] { typeof(string) }));
ctorIL.Emit(OpCodes.Stloc_0);
ctorIL.Emit(OpCodes.Ldarg_0);
ctorIL.Emit(OpCodes.Ldfld, scriptEngineField);
ctorIL.Emit(OpCodes.Ldloc_0);
ctorIL.Emit(OpCodes.Callvirt, typeof(ScriptEngine).GetMethod("Execute", new Type[] { typeof(string) }));
ctorIL.Emit(OpCodes.Nop);
ctorIL.Emit(OpCodes.Nop);
ctorIL.Emit(OpCodes.Stfld, jsFileFullPathField);
ctorIL.Emit(OpCodes.Ret);


and there's an exception called System.Reflection.TargetInvocationException when using it like this:



ICalculator calculator = (ICalculator)Activator.CreateInstance(t, new object[] { new JScriptEngine(), jsFileFullPath });


what's the problem?






Aucun commentaire:

Enregistrer un commentaire