Im compiling some code at runtime then loading the assembly into the current appdomain, however when i then try to do Type.GetType it cant find the type...
Here is how i compile the code...
public static Assembly CompileCode(string code)
{
Microsoft.CSharp.CSharpCodeProvider provider = new CSharpCodeProvider();
ICodeCompiler compiler = provider.CreateCompiler();
CompilerParameters compilerparams = new CompilerParameters();
compilerparams.GenerateExecutable = false;
compilerparams.GenerateInMemory = false;
foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
{
try
{
string location = assembly.Location;
if (!String.IsNullOrEmpty(location))
{
compilerparams.ReferencedAssemblies.Add(location);
}
}
catch (NotSupportedException)
{
// this happens for dynamic assemblies, so just ignore it.
}
}
CompilerResults results =
compiler.CompileAssemblyFromSource(compilerparams, code);
if (results.Errors.HasErrors)
{
StringBuilder errors = new StringBuilder("Compiler Errors :\r\n");
foreach (CompilerError error in results.Errors)
{
errors.AppendFormat("Line {0},{1}\t: {2}\n",
error.Line, error.Column, error.ErrorText);
}
throw new Exception(errors.ToString());
}
else
{
AppDomain.CurrentDomain.Load(results.CompiledAssembly.GetName());
return results.CompiledAssembly;
}
}
This bit fails after getting the type from the compiled assembly just fine, it does not seem to be able to find it using Type.GetType....
Assembly assem = RuntimeCodeCompiler.CompileCode(code);
string typeName =
String.Format("Peverel.AppFramework.Web.GenCode.ObjectDataSourceProxy_{0}",
safeTypeName);
Type t = assem.GetType(typeName); //This works just fine..
Type doesntWork = Type.GetType(t.AssemblyQualifiedName);
Type doesntWork2 = Type.GetType(t.Name);
....
Found this nice bit of code that ensures no matter how you load your assembly it is always available from Type.GetType.
My class for compiling code into the current appdomain now looks like :
public static class RuntimeCodeCompiler
{
private static volatile Dictionary<string, Assembly> cache = new Dictionary<string, Assembly>();
private static object syncRoot = new object();
static Dictionary<string, Assembly> assemblies = new Dictionary<string, Assembly>();
static RuntimeCodeCompiler()
{
AppDomain.CurrentDomain.AssemblyLoad += (sender, e) =>
{
assemblies[e.LoadedAssembly.FullName] = e.LoadedAssembly;
};
AppDomain.CurrentDomain.AssemblyResolve += (sender, e) =>
{
Assembly assembly = null;
assemblies.TryGetValue(e.Name, out assembly);
return assembly;
};
}
public static Assembly CompileCode(string code)
{
Microsoft.CSharp.CSharpCodeProvider provider = new CSharpCodeProvider();
ICodeCompiler compiler = provider.CreateCompiler();
CompilerParameters compilerparams = new CompilerParameters();
compilerparams.GenerateExecutable = false;
compilerparams.GenerateInMemory = false;
foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
{
try
{
string location = assembly.Location;
if (!String.IsNullOrEmpty(location))
{
compilerparams.ReferencedAssemblies.Add(location);
}
}
catch (NotSupportedException)
{
// this happens for dynamic assemblies, so just ignore it.
}
}
CompilerResults results =
compiler.CompileAssemblyFromSource(compilerparams, code);
if (results.Errors.HasErrors)
{
StringBuilder errors = new StringBuilder("Compiler Errors :\r\n");
foreach (CompilerError error in results.Errors)
{
errors.AppendFormat("Line {0},{1}\t: {2}\n",
error.Line, error.Column, error.ErrorText);
}
throw new Exception(errors.ToString());
}
else
{
AppDomain.CurrentDomain.Load(results.CompiledAssembly.GetName());
return results.CompiledAssembly;
}
}
public static Assembly CompileCodeOrGetFromCache(string code, string key)
{
bool exists = cache.ContainsKey(key);
if (!exists)
{
lock (syncRoot)
{
exists = cache.ContainsKey(key);
if (!exists)
{
cache.Add(key, CompileCode(code));
}
}
}
return cache[key];
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With