In the Roslyn Scripting API, it's possible to pass values to the script as the properties of a "globals" object.
Can something similar be done when using the workspace API?
Here's my sample code:
var options = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)
.WithOverflowChecks(true).WithOptimizationLevel(OptimizationLevel.Release)
.WithUsings("System", "System.Collections", "System.Collections.Generic", "System.Dynamic", "System.Linq");
string userCode = "... end user's code goes here...";
using (var workspace = new AdhocWorkspace() { })
{
string projName = "NewProject132";
var projectId = ProjectId.CreateNewId();
var projectInfo = ProjectInfo.Create(
projectId,
VersionStamp.Create(),
projName,
projName,
LanguageNames.CSharp,
isSubmission: true,
compilationOptions: options,
metadataReferences: references,
parseOptions: new CSharpParseOptions(kind: SourceCodeKind.Script, languageVersion: LanguageVersion.Latest));
var project = workspace.AddProject(projectInfo);
var id = DocumentId.CreateNewId(project.Id);
/*
how do I declare variables that are supposed to be visible to the user's code?
*/
var solution = project.Solution.AddDocument(id, project.Name, userCode);
var document = solution.GetDocument(id);
//get syntax and semantic errors
var syntaxTree = document.GetSyntaxTreeAsync().Result;
foreach (var syntaxError in syntaxTree.GetDiagnostics())
{
//...
}
var model = document.GetSemanticModelAsync().Result;
foreach (var syntaxError in model.GetDiagnostics(new TextSpan(0, userCode.Length)))
{
//...
}
var completionService = CompletionService.GetService(document);
var completions = completionService.GetCompletionsAsync(document, userCode.Length - 1).Result;
}
The document is being populated with the users script, but the script needs to be able to access some values from the host application.
As a last resort, I could add the variable declarations before the user's script, but that seems a bit messy and I'd like to avoid it if possible.