private void ValidateRunOptions(RunOptions opts) { if (opts.GetNamespace() == null || opts.GetNamespace().Length == 0) { throw new RunError("The namespace must not be blank"); } if (opts.GetClass() == null || opts.GetClass().Length == 0) { throw new RunError("The class must not be blank"); } if (opts.GetMethod() == null || opts.GetMethod().Length == 0) { throw new RunError("The method must not be blank"); } }
/// <summary> /// Runs a method in the compiled code based on the given options. If the code does not compile, /// it throws an exception. If the method cannot be run or is not found, it throws an exception. /// </summary> /// <param name="opts">The configuration based on which the method is run.</param> /// <returns>The result of invoking the method. If the method is void, the result is set to null.</returns> public object Run(RunOptions opts) { ValidateRunOptions(opts); using (var compileStream = new MemoryStream()) { EmitResult result = cSharpCompilation.Emit(compileStream); if (!result.Success) { throw CompilationError.Build(GetErrors()); } compileStream.Seek(0, SeekOrigin.Begin); Assembly assembly = AssemblyLoadContext.Default.LoadFromStream(compileStream); string namespaceAndClass = $"{opts.GetNamespace()}.{opts.GetClass()}"; var type = assembly.GetType(namespaceAndClass); if (type == null) { throw new RunError( $"Could not find class '{opts.GetClass()}' in namespace '{opts.GetNamespace()}'"); } var members = type.GetMember(opts.GetMethod()); if (members == null || members.Count() == 0) { throw new RunError( $"Could not find method '{opts.GetMethod()}' in class '{opts.GetClass()}' and namespace '{opts.GetNamespace()}'"); } var member = members.First() as MethodInfo; if (member == null) { throw new RunError( $"Could not find method '{opts.GetMethod()}' in class '{opts.GetClass()}' and namespace '{opts.GetNamespace()}'"); } var instance = assembly.CreateInstance(namespaceAndClass); return(member.Invoke(instance, opts.GetArgs())); } }