1

my goal is to write a class that can compile/serialize any piece of code. I am thinking of some ideas and it's just a concept, I don't expect you to write entire solution, I am thinking of best way to do that. I thought about two ideas:

  1. Create an interface in compiler class, then read interface method body and compile it into separate assembly using roslyn.
  2. Serialize expression tree.

AD 1. First concept

public class Runnable : IRunnable
{
    void Run();
}

public interface ICodeRunner
{
    void RunCode<T>() where T : IRunnable
}

public class CodeRunner : ICodeRunner
{
    public void RunCode<T>() where T : IRunnable
    {
        MethodInfo mi = typeof(T).GetMethod("Run");
        MethodBody mb = mi.GetMethodBody();
        // somehow get method body if possible and compile it using roslyn.
        // like this:
        // string syntaxTree = mb.GetMethodBodyToString() // this method doesn't exist. There must be a way to do that
        // CSharpCompilation compilation = CSharpCompilation.Create(
        //    "abc",
        //    new[] { syntaxTree },
        //    new[] { MetadataReference.CreateFromFile(typeof(object).Assembly.Location) },
        //    new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));

        // using (var dllStream = new FileStream(@"abc.dll", FileMode.OpenOrCreate))
        // using (var pdbStream = new FileStream(@"abc.pdb", FileMode.OpenOrCreate))
        // {
        //    var emitResult = compilation.Emit(dllStream, pdbStream);
        //    if (!emitResult.Success)
        //    {
        //        // emitResult.Diagnostics
        //    }
        // }
    }
}

The alternative is to serialize lambda as expression tree into a file, I saw some libraries to do that.
Are there any easier ways to this?

My general use case is to create a class that can serialize some code (logic) and payload into two separate files, send it over the wire and run piece of code + payload on a different machine. The interface is exe file and input file which is sent over the wire. Are there any ready solution for this problem?

Peter B
  • 22,460
  • 5
  • 32
  • 69
MistyK
  • 6,055
  • 2
  • 42
  • 76
  • 6
    This can't work in general because there exist constructs in IL that can't be expressed in C#; it's the exact problem decompilers face. For your particular use case you won't need to worry, if the source is C#, but if the source is C#, you already have a perfect serialization format -- it *is* the source. And if you only deal with expression trees generated at runtime so there is no source, see [here](http://stackoverflow.com/questions/217961/). – Jeroen Mostert Oct 13 '16 at 12:40
  • 3
    In general, I would be very uncomfortable sending arbitrary code over the wire, no matter the security precautions. If you can devise a domain-specific language for your payload instead, you'll have more work up front, but you'll save on maintenance in the long run. If you *are* going to send arbitrary code, don't bother with decompiling at all -- either just transfer the compiled executable as-is, or transfer the output of `ildasm` if you *must* have readable text. No need to use C# as an intermediary. – Jeroen Mostert Oct 13 '16 at 12:57
  • 2
    So you're trying to reinvent the wheel that's called COM/COM+? – CodeCaster Oct 13 '16 at 13:15

0 Answers0