Search code examples
c#csharpcodeprovider

How to unload assembly created by CSharpCodeProvider?


Problem

CSharpCodeProvider can be used to compile source .cs files into an assembly. However, the assembly is automatically loaded into the AppDomain.CurrentDomain by default. In my case, this is a problem because I need to be able to re-compile the assembly again during runtime, and since it's already loaded in the CurrentDomain, I can't unload that, so I'm stuck.

I have looked through the docs and there seems to be no way to set the target app domain. I have also tried searching it on Google and only found answers where Assembly.Load was used, which I don't think I can use because I need to compile from raw source code, not a .dll

How would one go about doing this? Are there any alternatives or workarounds?

Main program

using (var provider = new CSharpCodeProvider())
{
  param.OutputAssembly = "myCompiledMod"
  var classFileNames = new DirectoryInfo("C:/sourceCode").GetFiles("*.cs", SearchOption.AllDirectories).Select(fi => fi.FullName).ToArray();
  CompilerResults result = provider.CompileAssemblyFromFile(param, classFileNames);
  Assembly newAssembly = result.CompiledAssembly // The assembly is already in AppDomain.CurrentDomain!
  // If you try compile again, you'll get an error; that class Test already exists
}

C:/sourceCode/test.cs

public class Test {}


What I tried already

I already tried creating a new AppDomain and loading it in there. What happens is the assembly ends up being loaded in both domains.

// <snip>compile code</snip>
Evidence ev = AppDomain.CurrentDomain.Evidence;
AppDomain domain = AppDomain.CreateDomain("NewDomain", ev);
domain.Load(newAssembly);

Solution

  • The answer was to use CSharpCodeProvider().CreateCompiler() instead of just CSharpCodeProvider, and to set param.GenerateInMemory to false. Now I'm able to see line numbers and no visible assembly .dll files are being created, and especially not being locked. This allows for keeping an assembly in memory and reloading it when needed.