Loading an assembly generated by the Roslyn compiler

后端 未结 5 615
佛祖请我去吃肉
佛祖请我去吃肉 2020-12-31 17:54

I\'m generating a Greeter.dll using the Roslyn compiler. My problem occurs trying to load the DLL file.

Here\'s the code:

using System;

using Rosly         


        
5条回答
  •  情话喂你
    2020-12-31 18:24

    I stumbled across this and, even though you have an accepted answer, I don't think it's helpful in general. So, I'll just leave this here for future searchers like myself.

    The problem with the code is two things, which you would have found out by looking at the returned value from

    EmitResult result = compilation.Emit(file);
    

    If you look at the properties on the EmitResult object, you would have found that there were 2 errors in the results.Diagnostics member.

    1. Main method not found
    2. Couldn't find class Console

    So, to fix the problem, 1. You need to mark the output as a dll 2. You need to add 'using System;' to the code you're passing into the API or say 'System.Console.WriteLine'

    The following code works making changes to fix those two issues:

            var outputFile = "Greeter.dll";
            var syntaxTree = SyntaxTree.ParseCompilationUnit(@"
     // ADDED THE FOLLOWING LINE
    using System;
    
    class Greeter
    {
        public void Greet()
        {
            Console.WriteLine(""Hello, World"");
        }
    }");
            var compilation = Compilation.Create(outputFile,
                syntaxTrees: new[] { syntaxTree },
                references: new[] {
                    new AssemblyFileReference(typeof(object).Assembly.Location),
                    new AssemblyFileReference(typeof(Enumerable).Assembly.Location),
                },
    
    // ADDED THE FOLLOWING LINE
                options: new CompilationOptions(OutputKind.DynamicallyLinkedLibrary));
    
            using (var file = new FileStream(outputFile, FileMode.Create))
            {
                EmitResult result = compilation.Emit(file);
            }
    
            Assembly assembly = Assembly.LoadFrom("Greeter.dll");
    
            Type type = assembly.GetType("Greeter");
            var obj = Activator.CreateInstance(type);
    
            type.InvokeMember("Greet",
                BindingFlags.Default | BindingFlags.InvokeMethod,
                null,
                obj,
                null);
    
            Console.WriteLine(" to continue");
            Console.ReadLine();
    

提交回复
热议问题