Commit | Line | Data |
---|---|---|
01c97316 JM |
1 | using System; |
2 | using System.CodeDom.Compiler; | |
3 | using System.Collections.Generic; | |
4 | using System.Linq; | |
5 | using System.Text; | |
6 | using Microsoft.CSharp; | |
7 | ||
8 | public static class EvalProvider | |
9 | { | |
10 | public static Func<T, TResult> CreateEvalMethod<T, TResult>(string code, string[] usingStatements = null, string[] assemblies = null) | |
11 | { | |
12 | Type returnType = typeof(TResult); | |
13 | Type inputType = typeof(T); | |
14 | ||
15 | var includeUsings = new HashSet<string>(new[] { "System" }); | |
16 | includeUsings.Add(returnType.Namespace); | |
17 | includeUsings.Add(inputType.Namespace); | |
18 | if (usingStatements != null) | |
19 | foreach (var usingStatement in usingStatements) | |
20 | includeUsings.Add(usingStatement); | |
21 | ||
22 | using (CSharpCodeProvider compiler = new CSharpCodeProvider()) | |
23 | { | |
24 | var name = "F" + Guid.NewGuid().ToString().Replace("-", string.Empty); | |
25 | var includeAssemblies = new HashSet<string>(new[] { "system.dll" }); | |
26 | if (assemblies != null) | |
27 | foreach (var assembly in assemblies) | |
28 | includeAssemblies.Add(assembly); | |
29 | ||
30 | var parameters = new CompilerParameters(includeAssemblies.ToArray()) | |
31 | { | |
32 | GenerateInMemory = true | |
33 | }; | |
34 | ||
35 | string source = string.Format(@" | |
36 | {0} | |
37 | namespace {1} | |
38 | {{ | |
39 | public static class EvalClass | |
40 | {{ | |
41 | public static {2} Eval({3} arg) | |
42 | {{ | |
43 | {4} | |
44 | }} | |
45 | }} | |
46 | }}", GetUsing(includeUsings), name, returnType.Name, inputType.Name, code); | |
47 | ||
48 | var compilerResult = compiler.CompileAssemblyFromSource(parameters, source); | |
49 | var compiledAssembly = compilerResult.CompiledAssembly; | |
50 | var type = compiledAssembly.GetType(string.Format("{0}.EvalClass", name)); | |
51 | var method = type.GetMethod("Eval"); | |
52 | return (Func<T, TResult>)Delegate.CreateDelegate(typeof(Func<T, TResult>), method); | |
53 | } | |
54 | } | |
55 | ||
56 | private static string GetUsing(HashSet<string> usingStatements) | |
57 | { | |
58 | StringBuilder result = new StringBuilder(); | |
59 | foreach (string usingStatement in usingStatements) | |
60 | { | |
61 | result.AppendLine(string.Format("using {0};", usingStatement)); | |
62 | } | |
63 | return result.ToString(); | |
64 | } | |
65 | } | |
66 |