How to use a Roslyn scripting submission as an assembly in other Roslyn compilations

断了今生、忘了曾经 提交于 2019-12-05 07:08:11

I think I've solved the mystery. Here's what happens:

  • Create a script.
  • Get the script's compilation, but override the compilation options. Specifically, it uses the default ScriptClassName, which is Script rather than the one generated by the scripting API (e.g. Submission#0) - this is the crux of the matter.
  • Emit an assembly using the overridden options & load it into memory from the stream.
  • Run the script. At this point there are two distinct and incompatible assemblies with the same name in loaded into the AppDomain using byte arrays.
  • Add the stream as a metadata reference to a new compilation and use it in code. It compiles fine since it's using the assembly generated from overridden options. You would not be able to compile it using the actual assembly created by the script, since names like Submission#0 are illegal in C#. If it weren't then you could put the actual script Assembly instance in the globals and use it in OnAssemblyResolve.
  • Call method Baz with a parameter of type Submission#0+Foo and try to cast it to Script+Foo.

To conclude - I don't believe this is possible using the current Roslyn Scripting API. However, these APIs are not the only way to compile scripts. You can just create a compilation on your own and set the SourceCodeKind to Script. You'd have to do a lot yourself, like running the main script method, handling globals, etc. I've done something like this in RoslynPad because I wanted the script assemblies to load with PDBs (so exceptions would have line information).

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!