I’m working on a Uno-Project (V5.2) project where I’m using the Roslyn API to dynamically compile some code. However, I’m encountering an exception at the line where I call Emit on the Compilation object. Here is a simplified version of my code:
public async Task<Type> GenerateDynamicType(string classText)
{
try
{
SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(classText);
List<MetadataReference> references = new List<MetadataReference>();
if (OperatingSystem.IsBrowser())
{
var meta = await GetAssemblyMetadataReference(typeof(object).Assembly);
references.Add(meta);
}
else
{
var location = typeof(object).Assembly.Location;
references.Add(MetadataReference.CreateFromFile(location));
}
CSharpCompilation compilation = CSharpCompilation.Create($"ClassToXaml.Presentation.{Guid.NewGuid()}")
.WithOptions(new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary, concurrentBuild: false, optimizationLevel: OptimizationLevel.Release))
.AddReferences(references)
.AddSyntaxTrees(syntaxTree);
// Emit assembly to memory stream
using (var ms = new System.IO.MemoryStream())
{
EmitResult emitResult = compilation.Emit(ms);// Exception occurs here
if (!emitResult.Success)
{
var failures = emitResult.Diagnostics.Where(diagnostic => diagnostic.IsWarningAsError || diagnostic.Severity == DiagnosticSeverity.Error);
foreach (Diagnostic diagnostic in failures)
{
Console.WriteLine(diagnostic.GetMessage());
}
throw new InvalidOperationException("Failed to generate dynamic type.");
}
Assembly assembly = Assembly.Load(ms.ToArray());
return assembly.GetTypes().First();
}
}
catch (Exception ex)
{
await _navigator.ShowMessageDialogAsync(ex);
throw;
}
}
private async Task<MetadataReference?> GetAssemblyMetadataReference(Assembly assembly)
{
MetadataReference? ret = null;
// var assemblyName = assembly.GetName().Name;
var assemblyUrl = $"{assembly.GetName().Name}.dll";
try
{
var client = new HttpClient();
client.BaseAddress = new Uri("http://localhost:5001/");
var tmp = await client.GetAsync(assemblyUrl);
if (tmp.IsSuccessStatusCode)
{
var bytes = await tmp.Content.ReadAsByteArrayAsync();
ret = MetadataReference.CreateFromImage(bytes);
}
}
catch (Exception ex)
{
}
return ret;
}
When I run this code, I get an exception on the Emit line on the WASM head, The Other head i.e. Windows, WPF can able to execute that code, and I’m not sure what is causing it. The exception message is not very descriptive. Here are some additional details about the exception:
- Exception Type & Message: System.InvalidOperationException: Failed to generate dynamic type.
I’ve ensured that the code syntax is correct and all necessary references are added. What could be causing this issue, and how can I troubleshoot or fix it? Here is the code text for compile.
public class Name
{
public string maiden { get; set; }
public string suffix { get; set; }
public string givenName { get; set; }
public string middleName { get; set; }
public string surname { get; set; }
}
Things I’ve checked:
- The syntax of the code being compiled. i.e.
- The references provided to the compilation.
- WIndow and WPF projects can able to compile this code.
- Blazor WASM also can able to compile this code
Any insights or suggestions would be greatly appreciated!