C# 6.0 syntax on hosted scripts

81 views
Skip to first unread message

Ricardo Fuente

unread,
Oct 26, 2017, 5:52:45 AM10/26/17
to CS-Script
Hi Oleg,

I've been using CSSCript for quite a few years now and would like to write new scripts using some of the C# 6.0 new syntax, i.e., interpolated strings and auto-properties.
I've read documentation about it on: https://github.com/oleg-shilo/cs-script/wiki/Choosing-Compiler-Engine but cannot get it to work. In my application, I keep getting syntax errors whereas CSScriptNpp (Notepad++ plugin) successfully compiles the script.

Where is CSSCodeProvider.v4.6.dll located? Installing CSScript via NuGet only sets CSScriptLibrary.dll as usual.

FYI: I use AsmHelper(CSScript.LoadFiles(... for some of the scripts and (ISomeInterface)CSScript.Load for some others.

Oleg Shilo

unread,
Oct 26, 2017, 8:50:36 AM10/26/17
to cs-s...@googlegroups.com
When you are hosting CS-Script engine you don't need to use custom code provider if you access it via Evaluator interface. You just add CS-Script NuGet package and you are done.

However in your case you are not using Evaluator but rather Native CS-Script API. This means that you need to bring another package to your project -  "Microsoft.Net.Compilers". To simplify this you can just add one "CS-Script.RoslynProvider" package, which brings all dependencies that you might need. 

Depending on your VS settings it can add the package as project reference or as package.config. 

Inline image 2

In both cases NuGet does not copy the compilers in your build (Release/Debug) folder thus you need carefully instruct CS-Script where to find Roslyn compilers (C#7 compiler). 

packages.config

If you add this package via "package.config" you can use the Roslyn setup routine from the sample "Scripting.native.Roslyn.cs" file distributed with the package. NuGet will add it to your project

PackageReference

If you add this package via PackageReference it will only add to your project assembly references but not the sample file. The code below shows how to integrate Roslyn with the script engine in this case:
static void SetupRoslyn()
{
    var localDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
 
    CSScript.GlobalSettings.UseAlternativeCompiler = Path.Combine(localDir, "CSSRoslynProvider.dll");
    CSScript.GlobalSettings.RoslynDir = Environment.ExpandEnvironmentVariables(@"%USERPROFILE%\.nuget\packages\Microsoft.Net.Compilers\2.2.0\tools");
}
 
static void Main(string[] args)
{
    SetupRoslyn();
 
    var sayHello = CSScript.LoadDelegate<Action<string>>(
                            @"void SayHello(string greeting)
                              {
                                  Console.WriteLine($""Gritting: {greeting}!"");
                              }");
 
    sayHello("Hello World!");
}
Cheers,
Oleg

Ricardo Fuente

unread,
Oct 27, 2017, 8:29:36 AM10/27/17
to CS-Script
Thanks Oleg, that was fast indeed.

Following your indications I've been able to use the alternative compiler but I've got the feeling that my application now runs much more slowly. It runs quite a bunch of scripts, could it have a worse performance with Roslyn?

And second, and last question, does Roslyn needs every file contained in the \Microsoft.Net.Compilers\2.2.0\tools folder or just a couple of DLLs?
My app is delivered in a single package containing every DLL needed and I find that adding another folder just to achieve this wouldn't be 'neat'.

Thanks again for your work.

Oleg Shilo

unread,
Oct 29, 2017, 1:33:05 AM10/29/17
to cs-s...@googlegroups.com

You need to consider quite a few things.

You are using legacy API CS-Script.Native. It can only rely on CodeDom API, meaning that every script being executed is passed through csc.exe compiler. Either the one that comes with .NET (< C#6) or the one that comes from Roslyn (>=C#6). You are using Roslyn's csc.exe.

Roslyn and its C#7 comes with a hefty price tag attached. Roslyn compiler is horrible in term's of startup time. On my PC it takes ~3-4 seconds to load. Though consecutive compilations will be very fast due to the compiler binaries already being loaded in the memory. However the truth is that regardless which package the compiler comes (csc.ex) the compilation triggers forking another process and as such it is an expensive operation. Though forking the process is much faster on Linux. If one uses Roslyn compilers he needs to distribute Microsoft.Net.Compilers\2.2.0\tools. This is an unfortunate decision that Microsoft has made and nothing we can do about it. The topic fully covered in this discussion. Interestingly Mono does not imposes this restriction on developers as it includes Roslyn naturally in the framework.

All this means that your best strategy of improving scripting performance is to use CS-Script caching (or implement your own). Caching is an incredible simple concept borrowed from Python. Thus if your script text is not changes since the last execution it's never compiled and the compilation result from the previous execution is reused. If one uses caching correctly the performance of the scripting is 100% identical to the performance of the fully compiled .NET assembly. You can find information about caching on the CS-Script Wiki.

You also have another option to choose if caching for some reason does not fit your purpose. You can use newer API CS-Script.Evaluator (read more on Wiki). This API unifies all available scripting .NET approaches and allows user to switch the underlying compilers as he wish.

CSScript.EvaluatorConfig.Engine = EvaluatorEngine.Roslyn

Thus one can choose "EvaluatorEngine.CodeDom", which will be roughly equivalent of what you have right now. Though you can chose EvaluatorEngine.Roslyn, which is a slightly different flavor of compiler comparing to what you are using right now. This compiler is in fact in-process compiler thus it compiles scripts much faster. Another advantage is that you need to deploy much less files with your app. Only the files from your Release/Debug folder. Negatives - you cannot debug scripts and you'll still pay the price of the first loading of the compiler.

Ricardo Fuente

unread,
Oct 30, 2017, 6:19:52 AM10/30/17
to CS-Script
Thanks again for this thorough answer, Oleg.

In fact we are using CS-Script caching (slightly modified to choose a custom path) and that's why I appreciated the loss of performance.
After reading you, I think we'll have to study if we can easily change to CS-Script.Evaluator or keep on with the current approach.

Thank you very much for your support.
Reply all
Reply to author
Forward
0 new messages