I am working on a project that will use CodeDOM to create a class that evaluates a custom expression, creates an assembly for this class, and loads the assembly. Since there may be a fair number of user expressions, I would like to first create an AppDomain, create / load and execute a CodeDOM to build inside that AppDomain, and then unload the AppDomain.
I searched quite a lot and found many examples of how to load an existing assembly in AppDomain, but I cannot find it, which shows me how to create an assembly from AppDomain.
This example ( DynamicCode ) creates an assembly using CodeDOM and then loads it into AppDomain, however, the author generates the assembly to disk. I would rather create an assembly in memory, so I donโt need to control the cleanup of the generated assemblies. (although this creates a dll file in the temp folder).
Can someone give me an example of how to do this?
Any help would be greatly appreciated.
I added some excerpts from my code so that you can all understand what I still have:
private string CreateSource() { CodeCompileUnit codeUnit = new CodeCompileUnit(); CodeNamespace codeNamespace = new CodeNamespace(Namespace); CodeTypeDeclaration codeClass = new CodeTypeDeclaration { Name = "ExpressionEvaluator", IsClass = true, TypeAttributes = TypeAttributes.Public | TypeAttributes.Sealed }; codeNamespace.Types.Add(codeClass); codeUnit.Namespaces.Add(codeNamespace); AddMethods(codeClass); string result = GenerateSourceCode(codeUnit); return result.ToString(); } private CompilerResults CompileSource(string source) { using (CodeDomProvider provider = new CSharpCodeProvider()) { CompilerParameters parameters = CreateCompilerParameters(); CompilerResults result = CompileCode(provider, parameters, source); return result; } } private static CompilerParameters CreateCompilerParameters() { CompilerParameters result = new CompilerParameters { CompilerOptions = "/target:library", GenerateExecutable = false, GenerateInMemory = true }; result.ReferencedAssemblies.Add("System.dll"); return result; } private object RunEvaluator(CompilerResults compilerResults) { object result = null; Assembly assembly = compilerResults.CompiledAssembly; if (assembly != null) { string className = "ExpressionEvaluator"; object instance = assembly.CreateInstance("Lab.ExpressionEvaluator"); Module[] modules = assembly.GetModules(false); Type type = (from t in modules[0].GetTypes() where t.Name == className select t).FirstOrDefault(); MethodInfo method = (from m in type.GetMethods() where m.Name == "Evaluate" select m).FirstOrDefault(); result = method.Invoke(instance, null); } else { throw new Exception("Unable to load Evaluator assembly"); } return result; }
I believe that these code snippets show the main functions of my project. Now all I have to do is wrap it in my own AppDomain.
source share