如何为非提交模式的Roslyn脚本项目设置基类
How to Set Base Class for Script Documents in Roslyn Without Enabling Submission Mode
It sounds like you're stuck trying to assign a base class to your script documents in Roslyn's AdhocWorkspace—since enabling isSubmission: true breaks your existing code, let's solve this without disrupting your current setup.
The Core Problem
When your project has isSubmission: false, the hostObjectType parameter in ProjectInfo.Create() gets ignored. Roslyn only uses that parameter for submission-style projects, which isn't an option for you here. Instead, we can configure each individual script document to inherit from your host type directly.
Step-by-Step Fix
- Cache the Host Type
First, add a static field to your compiler class to store the incominghosttype—this lets us reference it when creating new documents:
private static Type _hostType; // Add this static field to your class public static async Task Init(Type host, params Assembly[] assemblies) { await Task.Run(() => { _hostType = host; // Save the host type for later use IsInitialized = true; workspace = new AdhocWorkspace(); var compilationOptions = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary, allowUnsafe: true, usings: new string[] { "CCreative" }, platform: Platform.X64) .WithMetadataImportOptions(MetadataImportOptions.All); var scriptProjectInfo = ProjectInfo.Create(ProjectId.CreateNewId(), VersionStamp.Create(), "Script", "Script", LanguageNames.CSharp, isSubmission: false, hostObjectType: host) .WithMetadataReferences(assemblies.Select(x => MetadataReference.CreateFromFile(x.Location, default, x.Location.Contains("CCreative") ? new CCreativeDocumentationProvider() : null))) .WithCompilationOptions(compilationOptions); project = workspace.AddProject(scriptProjectInfo); workspace.TryApplyChanges(project.Solution.WithOptions(GetOptions(workspace))); }); }
- Set Parse Options for Each Script Document
When creating a new script document, useScriptParseOptionsto explicitly define your host type as the script's base class. This tells Roslyn to treat the script as inheriting from your host type, even without submission mode enabled:
public static DocumentId AddDocument(string text) { // Configure script-specific parse options with your host type as the base var scriptParseOptions = ScriptParseOptions.Default .WithHostObjectType(_hostType) .WithLanguageVersion(LanguageVersion.Latest); // Adjust to your target C# version var scriptDocumentInfo = DocumentInfo.Create( DocumentId.CreateNewId(project.Id), "Script", sourceCodeKind: SourceCodeKind.Script, loader: TextLoader.From(TextAndVersion.Create(SourceText.From(text), VersionStamp.Create())), parseOptions: scriptParseOptions); // Attach the custom parse options var scriptDocument = workspace.AddDocument(scriptDocumentInfo); project = scriptDocument.Project; workspace.TryApplyChanges(project.Solution); return scriptDocument.Id; }
Important Notes
- Verify Host Assembly Reference: Make sure the assembly containing your
hosttype is included in theassembliesarray passed toInit()—Roslyn needs to resolve the type during compilation. - Preserve Existing Behavior: By keeping
isSubmission: falseon the project, all your existing code that relies on the non-submission project structure will continue to work as before. - Script Functionality: Your script code will now be able to access members of the host type directly, just like in submission mode, without any breaking changes to your setup.
内容的提问来源于stack exchange,提问作者Jan Tamis Kossen
相关产品推荐
相关产品推荐

