using Microsoft.CSharp; using System; using System.CodeDom.Compiler; using System.Linq; using System.Reflection; using System.Text; namespace FormulaEnginePoC.CSharpProvider { public class CodeCompiler where TDelegate : Delegate { private CompilerResults _compilerResults; public TDelegate CompiledDelegate { get; private set; } public CompilerError[] CompilerErrors => _compilerResults?.Errors.Cast().ToArray() ?? throw new InvalidOperationException("Not compile yet"); public void Compile(string fullTypeName, string methodName, string code, params string[] referencedAssemblies) { var codeProvider = new CSharpCodeProvider(); var parameters = new CompilerParameters { GenerateInMemory = true , GenerateExecutable = false , ReferencedAssemblies = { "system.dll" } }; foreach (var item in referencedAssemblies) { parameters.ReferencedAssemblies.Add(item); } _compilerResults = codeProvider.CompileAssemblyFromSource(parameters, code); if (_compilerResults.Errors.HasErrors) { var sb = new StringBuilder(); foreach (CompilerError item in _compilerResults.Errors) { sb.AppendLine($"{item.ErrorText}({item.ErrorNumber})"); } throw new ArgumentException("Compile fail:" + sb); } var type = _compilerResults.CompiledAssembly.GetType(fullTypeName); var method = type.GetMethod(methodName, BindingFlags.Public | BindingFlags.Static) ?? throw new MissingMethodException("Unable get static method from compiled assembly"); CompiledDelegate = (TDelegate)Delegate.CreateDelegate(typeof(TDelegate), method); } } }