CodeCompiler.cs 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. using Microsoft.CSharp;
  2. using System;
  3. using System.CodeDom.Compiler;
  4. using System.Linq;
  5. using System.Reflection;
  6. using System.Text;
  7. namespace FormulaEnginePoC.CSharpProvider
  8. {
  9. public class CodeCompiler<TDelegate> where TDelegate : Delegate
  10. {
  11. private CompilerResults _compilerResults;
  12. public TDelegate CompiledDelegate { get; private set; }
  13. public CompilerError[] CompilerErrors => _compilerResults?.Errors.Cast<CompilerError>().ToArray()
  14. ?? throw new InvalidOperationException("Not compile yet");
  15. public void Compile(string fullTypeName, string methodName, string code, params string[] referencedAssemblies)
  16. {
  17. var codeProvider = new CSharpCodeProvider();
  18. var parameters = new CompilerParameters
  19. {
  20. GenerateInMemory = true
  21. , GenerateExecutable = false
  22. , ReferencedAssemblies =
  23. {
  24. "system.dll"
  25. }
  26. };
  27. foreach (var item in referencedAssemblies)
  28. {
  29. parameters.ReferencedAssemblies.Add(item);
  30. }
  31. _compilerResults = codeProvider.CompileAssemblyFromSource(parameters, code);
  32. if (_compilerResults.Errors.HasErrors)
  33. {
  34. var sb = new StringBuilder();
  35. foreach (CompilerError item in _compilerResults.Errors)
  36. {
  37. sb.AppendLine($"{item.ErrorText}({item.ErrorNumber})");
  38. }
  39. throw new ArgumentException("Compile fail:" + sb);
  40. }
  41. var type = _compilerResults.CompiledAssembly.GetType(fullTypeName);
  42. var method = type.GetMethod(methodName, BindingFlags.Public | BindingFlags.Static)
  43. ?? throw new MissingMethodException("Unable get static method from compiled assembly");
  44. CompiledDelegate = (TDelegate)Delegate.CreateDelegate(typeof(TDelegate), method);
  45. }
  46. }
  47. }