From 0a7aa7454201d0f7e677ed76ef33366df6c268b7 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Fri, 5 Jun 2026 10:19:34 +0200 Subject: [PATCH] Resolve LanguageService/Settings fresh so the tree filter honours current settings ILSpyTreeNode cached the SettingsService (and LanguageService) in a static field that was never invalidated. In the headless suite the MEF container is rebuilt per test, so from the second test onward the filter cascade (ApplyFilterToChild / OnIsVisibleChanged) read a previous test's disposed SettingsService and its stale ShowApiLevel. A test that set ShowApiLevel=All on its own fresh settings then expanded a large type still had ~a third of the members marked IsHidden against the stale level, so the flattener dropped them and the rows never realised -- surfacing as an order-dependent timeout (NonPublic_Member_Rows_Render and the in-place refilter test). GetSuffixString already resolves the service fresh for exactly this reason; apply the same to CurrentLanguageSettings and LanguageService and drop the dead caches. A warm GetExport is a dictionary lookup, and in production (one container for the app lifetime) behaviour is unchanged. --- ILSpy/TreeNodes/ILSpyTreeNode.cs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/ILSpy/TreeNodes/ILSpyTreeNode.cs b/ILSpy/TreeNodes/ILSpyTreeNode.cs index 97956ba37..e4b569bfc 100644 --- a/ILSpy/TreeNodes/ILSpyTreeNode.cs +++ b/ILSpy/TreeNodes/ILSpyTreeNode.cs @@ -37,15 +37,15 @@ namespace ILSpy.TreeNodes { IEnumerable ITreeNode.Children => Children.OfType(); - static LanguageService? cachedLanguageService; - static SettingsService? cachedSettingsService; - /// /// Resolves the LanguageService from the MEF composition. Tree nodes use this to access /// the active for formatting their . + /// Resolved fresh each call: a static cache can hold a previous test's composition root in + /// headless sweeps (the container is rebuilt per test), and a warm GetExport is a dictionary + /// lookup. See for the same rationale. /// protected static LanguageService LanguageService - => cachedLanguageService ??= AppComposition.Current.GetExport(); + => AppComposition.Current.GetExport(); /// /// The active , or when composition @@ -58,8 +58,11 @@ namespace ILSpy.TreeNodes get { try { - var service = cachedSettingsService ??= AppComposition.Current.GetExport(); - return service.SessionSettings.LanguageSettings; + // Resolve fresh each call -- a static cache can hold a previous test's composition + // root in headless sweeps (the container is rebuilt per test, so a cached + // SettingsService reports a stale ShowApiLevel and the filter cascade hides nodes + // that the current settings would show). A warm GetExport is a dictionary lookup. + return AppComposition.Current.GetExport().SessionSettings.LanguageSettings; } catch {