private SvgDocument CreateDocument(string userCode) { var source = $@"using System; using System.Drawing; using System.IO; using Svg; class Program {{ public static SvgDocument CreateDocument() {{ SvgDocument svgDoc = null; {userCode} return svgDoc; }} }} "; var sourcePath = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly()?.Location ?? string.Empty); var sourceText = SourceText.From(source, Encoding.UTF8); var options = CSharpParseOptions.Default .WithLanguageVersion(LanguageVersion.CSharp8); var syntaxTree = CSharpSyntaxTree.ParseText( sourceText, options ) .WithFilePath(Path.Combine(sourcePath, "Program.cs")); var runtimeDirectoryPath = System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory(); var references = new MetadataReference[] { MetadataReference.CreateFromFile(typeof(object).Assembly.Location), MetadataReference.CreateFromFile(Path.Combine(runtimeDirectoryPath, "mscorlib.dll")), MetadataReference.CreateFromFile(Path.Combine(runtimeDirectoryPath, "System.Runtime.dll")), #if NETFRAMEWORK MetadataReference.CreateFromFile(Path.Combine(runtimeDirectoryPath, "System.Drawing.dll")), MetadataReference.CreateFromFile(Path.Combine(runtimeDirectoryPath, "System.Xml.dll")), #else MetadataReference.CreateFromFile(Path.Combine(runtimeDirectoryPath, "System.Drawing.Primitives.dll")), MetadataReference.CreateFromFile(Path.Combine(runtimeDirectoryPath, "System.Private.Xml.dll")), MetadataReference.CreateFromFile(Path.Combine(runtimeDirectoryPath, "System.Xml.ReaderWriter.dll")), #endif MetadataReference.CreateFromFile(Path.Combine(sourcePath, "Svg.dll")), }; var compilationOptions = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary) .WithOptimizationLevel(OptimizationLevel.Release); var compilation = CSharpCompilation.Create( "ConsoleApp", new[] { syntaxTree }, references, compilationOptions); using (var stream = new MemoryStream()) { var emitResult = compilation.Emit(stream); if (!emitResult.Success) { var messages = new StringBuilder(); foreach (var diagnostic in emitResult.Diagnostics) { var pos = diagnostic.Location.GetLineSpan(); var location = $"({pos.StartLinePosition.Line + 1 - 10},{pos.StartLinePosition.Character + 1})"; messages.AppendLine($"{location}: {diagnostic.Severity} {diagnostic.Id}: {diagnostic.GetMessage()}"); } throw new InvalidProgramException(messages.ToString()); } #if !NETFRAMEWORK var assemblyLoadContext = new System.Runtime.Loader.AssemblyLoadContext(compilation.AssemblyName, true); #endif try { stream.Seek(0, SeekOrigin.Begin); #if NETFRAMEWORK var assembly = System.Reflection.Assembly.Load(stream.ToArray()); #else var assembly = assemblyLoadContext.LoadFromStream(stream); #endif var type = assembly.GetType("Program"); var method = type?.GetMethod("CreateDocument"); return(method?.Invoke(null, null) as SvgDocument); } catch (Exception ex) { throw ex.InnerException ?? ex; } #if !NETFRAMEWORK finally { assemblyLoadContext.Unload(); } #endif } }
public Type GenerateProxy(Type serviceContract) { var assemblyName = new AssemblyName(serviceContract.FullName + ".Proxy"); bool saveAssembly; var assemblyBuilder = CreateAssemblyBuilder(AppDomain.CurrentDomain, assemblyName, out saveAssembly); var moduleBuilder = CreateModuleBuilder(assemblyBuilder, saveAssembly); var clientType = CreateClientType(serviceContract, moduleBuilder); if (saveAssembly) { #if NET48 assemblyBuilder.Save(assemblyName.Name + ".dll"); #else // Don't take a dedendency on Lokad.ILPack.nupkg. Also, at the time of this writing // the most current version (0.6.1) did caused an exception. Building the repo // (74f8fe7) and referencing the created DLL did work. string directory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); string helper = Path.Combine(directory, "Lokad.ILPack.dll"); bool foundHelper = false; if (!File.Exists(helper)) { helper = Environment.GetEnvironmentVariable("WCFPROXY_SAVE_HELPER"); if (!string.IsNullOrEmpty(helper) && File.Exists(helper)) { foundHelper = true; } } else { foundHelper = true; } if (foundHelper) { var ldx = new System.Runtime.Loader.AssemblyLoadContext(helper, true); try { var hass = ldx.LoadFromAssemblyPath(helper); var genType = hass.GetType("Lokad.ILPack.AssemblyGenerator"); var genMethod = genType.GetMethod("GenerateAssembly", new[] { typeof(Assembly), typeof(string) }); var generator = Activator.CreateInstance(genType); string outputFile = Path.Combine(AssemblyOutputDirectory, assemblyName.Name + ".dll"); genMethod.Invoke(generator, new object[] { assemblyBuilder, outputFile }); } finally { ldx.Unload(); } } else { Trace.WriteLine($"Saving assembly to file is not supported. " + $"File '{AssemblyOutputDirectory}\\{assemblyName}.dll' not created"); } #endif } return(clientType); }