From 34e1a78e68fb8b4ad7c9c662eccda71bc207988b Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Wed, 12 Aug 2026 16:39:38 -0400 Subject: [PATCH] fix(scripts): memoize missing-assembly resolution in the UI script editor/sandbox --- .../ScriptAnalysis/ScriptAnalysisService.cs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/ZB.MOM.WW.ScadaBridge.CentralUI/ScriptAnalysis/ScriptAnalysisService.cs b/src/ZB.MOM.WW.ScadaBridge.CentralUI/ScriptAnalysis/ScriptAnalysisService.cs index dd1d3698..5157ed09 100644 --- a/src/ZB.MOM.WW.ScadaBridge.CentralUI/ScriptAnalysis/ScriptAnalysisService.cs +++ b/src/ZB.MOM.WW.ScadaBridge.CentralUI/ScriptAnalysis/ScriptAnalysisService.cs @@ -41,6 +41,21 @@ namespace ZB.MOM.WW.ScadaBridge.CentralUI.ScriptAnalysis; /// public class ScriptAnalysisService { + /// + /// Base Roslyn scripting options for every editor analysis, shared by + /// and by the per-request options derived from it + /// (ScriptOptions is immutable-with-copy, so derivations inherit this). + /// + /// + /// Editor diagnostics compile on EVERY analysis request — one per debounced + /// keystroke burst — and Roslyn's default resolver re-resolves the transitive + /// closure of these references through MetadataReference.CreateFromFile on + /// every one of them, minting fresh AssemblyMetadataPEReader → + /// NativeHeapMemoryBlock copies that nothing disposes. The shared + /// memoizes those + /// resolutions process-wide; see its doc for the full mechanism. + /// + /// private static readonly ScriptOptions DefaultOptions = ScriptOptions.Default .AddReferences( typeof(object).Assembly, @@ -50,6 +65,7 @@ public class ScriptAnalysisService typeof(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo).Assembly, typeof(Commons.Types.ScriptParameters).Assembly, typeof(SandboxScriptHost).Assembly) + .WithMetadataResolver(SharedTrust.CachingScriptMetadataResolver.Instance) .AddImports( "System", "System.Collections.Generic",