Ejemplo n.º 1
0
        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
            }
        }
Ejemplo n.º 2
0
        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);
        }