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.HideBySig |
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?