Skip to content

Commit

Permalink
Decouple services to reduce circular dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
tom-englert committed Oct 26, 2024
1 parent daea9e6 commit 8ad35c4
Show file tree
Hide file tree
Showing 11 changed files with 120 additions and 107 deletions.
5 changes: 1 addition & 4 deletions ILSpy/AboutPage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,7 @@ public sealed class AboutPageCommand(AssemblyTreeModel assemblyTreeModel) : Simp
{
public override void Execute(object parameter)
{
assemblyTreeModel.NavigateTo(
new RequestNavigateEventArgs(new Uri("resource://aboutpage"), null),
inNewTabPage: true
);
assemblyTreeModel.NavigateTo(new(new("resource://aboutpage"), null), inNewTabPage: true);
}
}

Expand Down
2 changes: 2 additions & 0 deletions ILSpy/Analyzers/AnalyzeCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ public void Execute(TextViewContext context)
}
}

[Export]
[Shared]
public sealed class AnalyzeCommand(AssemblyTreeModel assemblyTreeModel, AnalyzerTreeViewModel analyzerTreeViewModel) : SimpleCommand
{
public override bool CanExecute(object parameter)
Expand Down
1 change: 1 addition & 0 deletions ILSpy/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ private static bool InitializeDependencyInjection(SettingsService settingsServic
services.AddSingleton(_ => ExportProvider);
// Add the docking manager
services.AddSingleton(serviceProvider => serviceProvider.GetService<MainWindow>().DockManager);
services.AddTransient(serviceProvider => serviceProvider.GetService<AssemblyTreeModel>().AssemblyList);

var serviceProvider = services.BuildServiceProvider(new ServiceProviderOptions { ValidateOnBuild = true });

Expand Down
53 changes: 50 additions & 3 deletions ILSpy/AssemblyTree/AssemblyTreeModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,13 @@
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.TypeSystem.Implementation;
using ICSharpCode.ILSpy.AppEnv;
using ICSharpCode.ILSpy.Docking;
using ICSharpCode.ILSpy.Properties;
using ICSharpCode.ILSpy.Search;
using ICSharpCode.ILSpy.TextView;
using ICSharpCode.ILSpy.TreeNodes;
using ICSharpCode.ILSpy.Updates;
using ICSharpCode.ILSpy.ViewModels;
using ICSharpCode.ILSpyX;
using ICSharpCode.ILSpyX.Settings;
using ICSharpCode.ILSpyX.TreeView;

using TomsToolbox.Composition;
Expand Down Expand Up @@ -90,6 +88,13 @@ public AssemblyTreeModel(AboutPage aboutPage, SearchPaneModel searchPaneModel, S

MessageBus<NavigateToReferenceEventArgs>.Subscribers += JumpToReference;
MessageBus<SettingsChangedEventArgs>.Subscribers += (sender, e) => Settings_PropertyChanged(sender, e);
MessageBus<ApplySessionSettingsEventArgs>.Subscribers += ApplySessionSettings;
MessageBus<ActiveTabPageChangedEventArgs>.Subscribers += ActiveTabPageChanged;
MessageBus<ResetLayoutEventArgs>.Subscribers += ResetLayout;
MessageBus<MainWindowLoadedEventArgs>.Subscribers += (_, _) => {
Initialize();
Show();
};

refreshThrottle = new DispatcherThrottle(DispatcherPriority.Background, RefreshInternal);

Expand Down Expand Up @@ -442,7 +447,6 @@ private void ShowAssemblyList(AssemblyList assemblyList)

AssemblyList.CollectionChanged -= assemblyList_CollectionChanged;
AssemblyList = assemblyList;

assemblyList.CollectionChanged += assemblyList_CollectionChanged;

assemblyListTreeNode = new(assemblyList) {
Expand Down Expand Up @@ -997,5 +1001,48 @@ public void OpenFiles(string[] fileNames, bool focusNode = true)

LoadAssemblies(fileNames, focusNode: focusNode);
}

private void ApplySessionSettings(object? sender, ApplySessionSettingsEventArgs e)
{
var settings = e.SessionSettings;

settings.ActiveAssemblyList = AssemblyList.ListName;
settings.ActiveTreeViewPath = SelectedPath;
settings.ActiveAutoLoadedAssembly = GetAutoLoadedAssemblyNode(SelectedItem);
}

private static string? GetAutoLoadedAssemblyNode(SharpTreeNode? node)
{
var assemblyTreeNode = node?
.AncestorsAndSelf()
.OfType<AssemblyTreeNode>()
.FirstOrDefault();

var loadedAssembly = assemblyTreeNode?.LoadedAssembly;

return loadedAssembly is not { IsLoaded: true, IsAutoLoaded: true }
? null
: loadedAssembly.FileName;
}

private void ActiveTabPageChanged(object? sender, ActiveTabPageChangedEventArgs e)
{
if (e.ViewState is not { } state)
return;

if (state.DecompiledNodes != null)
{
SelectNodes(state.DecompiledNodes);
}
else
{
NavigateTo(new(state.ViewedUri, null));
}

}
private void ResetLayout(object? sender, ResetLayoutEventArgs e)
{
RefreshDecompiledView();
}
}
}
36 changes: 12 additions & 24 deletions ILSpy/Docking/DockWorkspace.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,23 +50,16 @@ public class DockWorkspace : ObservableObject, ILayoutUpdateStrategy
{
private readonly IExportProvider exportProvider;

private SettingsService SettingsService { get; }

private LanguageService LanguageService => exportProvider.GetExportedValue<LanguageService>();

private SessionSettings SessionSettings { get; }

private readonly ObservableCollection<TabPageModel> tabPages = [];

private DockingManager DockingManager => exportProvider.GetExportedValue<DockingManager>();

private AssemblyTreeModel AssemblyTreeModel => exportProvider.GetExportedValue<AssemblyTreeModel>();

public DockWorkspace(SettingsService settingsService, IExportProvider exportProvider)
{
this.exportProvider = exportProvider;

SettingsService = settingsService;
SessionSettings = settingsService.SessionSettings;

this.tabPages.CollectionChanged += TabPages_CollectionChanged;
Expand Down Expand Up @@ -127,7 +120,7 @@ private void TabPages_CollectionChanged(object sender, NotifyCollectionChangedEv

public void AddTabPage(TabPageModel tabPage = null)
{
tabPages.Add(tabPage ?? new TabPageModel(AssemblyTreeModel, SettingsService, LanguageService));
tabPages.Add(tabPage ?? exportProvider.GetExportedValue<TabPageModel>());
}

public ReadOnlyObservableCollection<TabPageModel> TabPages { get; }
Expand Down Expand Up @@ -169,22 +162,13 @@ public TabPageModel ActiveTabPage {
}
set {
if (!SetProperty(ref activeTabPage, value))
{
return;
}

var state = value?.GetState();
if (state != null)
{
if (state.DecompiledNodes != null)
{
AssemblyTreeModel.SelectNodes(state.DecompiledNodes);
}
else
{
AssemblyTreeModel.NavigateTo(new(state.ViewedUri, null));
}
}
if (state == null)
return;

MessageBus.Send(this, new ActiveTabPageChangedEventArgs(value?.GetState()));
}
}

Expand All @@ -195,8 +179,11 @@ public PaneModel ActivePane {

public void InitializeLayout()
{
// Make sure there is at least one tab open
AddTabPage();
if (tabPages.Count == 0)
{
// Make sure there is at least one tab open
AddTabPage();
}

DockingManager.LayoutUpdateStrategy = this;
XmlLayoutSerializer serializer = new XmlLayoutSerializer(DockingManager);
Expand Down Expand Up @@ -262,7 +249,8 @@ internal void ResetLayout()
CloseAllTabs();
SessionSettings.DockLayout.Reset();
InitializeLayout();
App.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, AssemblyTreeModel.RefreshDecompiledView);

App.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, () => MessageBus.Send(this, new ResetLayoutEventArgs()));
}

static readonly PropertyInfo previousContainerProperty = typeof(LayoutContent).GetProperty("PreviousContainer", BindingFlags.NonPublic | BindingFlags.Instance);
Expand Down
3 changes: 2 additions & 1 deletion ILSpy/MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
xmlns:viewModels="clr-namespace:ICSharpCode.ILSpy.ViewModels"
xmlns:composition="urn:TomsToolbox.Composition"
xmlns:commands="clr-namespace:ICSharpCode.ILSpy.Commands"
xmlns:analyzers="clr-namespace:ICSharpCode.ILSpy.Analyzers"
d:DataContext="{d:DesignInstance local:MainWindowViewModel}">
<Window.Resources>

Expand All @@ -38,7 +39,7 @@
</b:Interaction.Behaviors>

<Window.InputBindings>
<KeyBinding Key="R" Modifiers="Control" Command="{Binding AnalyzeCommand}" />
<KeyBinding Key="R" Modifiers="Control" Command="{composition:Import analyzers:AnalyzeCommand}" />
<KeyBinding Key="Z" Modifiers="Control" Command="{x:Static NavigationCommands.BrowseBack}" />
</Window.InputBindings>

Expand Down
54 changes: 5 additions & 49 deletions ILSpy/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,8 @@
using System.Windows.Media;
using System.Windows.Threading;

using AvalonDock.Layout.Serialization;

using ICSharpCode.ILSpy.AssemblyTree;
using ICSharpCode.ILSpy.TreeNodes;
using ICSharpCode.ILSpy.Updates;
using ICSharpCode.ILSpyX.FileLoaders;
using ICSharpCode.ILSpyX.Settings;
using ICSharpCode.ILSpyX.TreeView;

using Screen = System.Windows.Forms.Screen;

Expand All @@ -50,16 +44,10 @@ namespace ICSharpCode.ILSpy
#pragma warning disable MEF003 // Main window is a singleton
partial class MainWindow
{
private readonly AssemblyTreeModel assemblyTreeModel;
private readonly IEnumerable<IFileLoader> fileLoaders;
private readonly MenuService menuService;
private readonly SettingsService settingsService;

public MainWindow(MainWindowViewModel mainWindowViewModel, AssemblyTreeModel assemblyTreeModel, IEnumerable<IFileLoader> fileLoaders, MenuService menuService, SettingsService settingsService)
public MainWindow(MainWindowViewModel mainWindowViewModel, MenuService menuService, SettingsService settingsService)
{
this.assemblyTreeModel = assemblyTreeModel;
this.fileLoaders = fileLoaders;
this.menuService = menuService;
this.settingsService = settingsService;

// Make sure Images are initialized on the UI thread.
Expand All @@ -69,16 +57,10 @@ public MainWindow(MainWindowViewModel mainWindowViewModel, AssemblyTreeModel ass

InitializeComponent();

InitFileLoaders();

Dispatcher.BeginInvoke(DispatcherPriority.Background, () => {
mainWindowViewModel.Workspace.InitializeLayout();
menuService.Init(mainMenu, toolBar, InputBindings);

Dispatcher.BeginInvoke(DispatcherPriority.Background, () => {
assemblyTreeModel.Initialize();
assemblyTreeModel.Show();
});
MessageBus.Send(this, new MainWindowLoadedEventArgs());
});
}

Expand All @@ -90,18 +72,6 @@ void SetWindowBounds(Rect bounds)
this.Height = bounds.Height;
}

#region File Loader extensibility

void InitFileLoaders()
{
// TODO
foreach (var loader in fileLoaders)
{
}
}

#endregion

#region Message Hook

protected override void OnSourceInitialized(EventArgs e)
Expand Down Expand Up @@ -251,27 +221,13 @@ protected override void OnClosing(CancelEventArgs e)

var sessionSettings = snapshot.GetSettings<SessionSettings>();

sessionSettings.ActiveAssemblyList = assemblyTreeModel.AssemblyList.ListName;
sessionSettings.ActiveTreeViewPath = assemblyTreeModel.SelectedPath;
sessionSettings.ActiveAutoLoadedAssembly = GetAutoLoadedAssemblyNode(assemblyTreeModel.SelectedItem);
MessageBus.Send(this, new ApplySessionSettingsEventArgs(sessionSettings));

sessionSettings.WindowBounds = this.RestoreBounds;
sessionSettings.DockLayout.Serialize(new XmlLayoutSerializer(DockManager));
sessionSettings.DockLayout.Serialize(new(DockManager));

snapshot.Save();
}

private static string GetAutoLoadedAssemblyNode(SharpTreeNode node)
{
var assemblyTreeNode = node?
.AncestorsAndSelf()
.OfType<AssemblyTreeNode>()
.FirstOrDefault();

var loadedAssembly = assemblyTreeNode?.LoadedAssembly;

return loadedAssembly is not { IsLoaded: true, IsAutoLoaded: true }
? null
: loadedAssembly.FileName;
}
}
}
6 changes: 1 addition & 5 deletions ILSpy/MainWindowViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@

using System.Composition;

using ICSharpCode.ILSpy.Analyzers;
using ICSharpCode.ILSpy.AssemblyTree;
using ICSharpCode.ILSpy.Docking;
using ICSharpCode.ILSpyX;

Expand All @@ -29,7 +27,7 @@ namespace ICSharpCode.ILSpy
{
[Export]
[Shared]
public class MainWindowViewModel(AssemblyTreeModel assemblyTreeModel, AnalyzerTreeViewModel analyzerTreeViewModel, SettingsService settingsService, LanguageService languageService, DockWorkspace dockWorkspace) : ObservableObject
public class MainWindowViewModel(SettingsService settingsService, LanguageService languageService, DockWorkspace dockWorkspace) : ObservableObject
{
public DockWorkspace Workspace { get; } = dockWorkspace;

Expand All @@ -38,7 +36,5 @@ public class MainWindowViewModel(AssemblyTreeModel assemblyTreeModel, AnalyzerTr
public LanguageService LanguageService => languageService;

public AssemblyListManager AssemblyListManager => settingsService.AssemblyListManager;

public AnalyzeCommand AnalyzeCommand { get; } = new(assemblyTreeModel, analyzerTreeViewModel);
}
}
19 changes: 11 additions & 8 deletions ILSpy/TextView/DecompilerTextView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@

using Microsoft.Win32;

using TomsToolbox.Composition;
using TomsToolbox.Wpf;

using ResourceKeys = ICSharpCode.ILSpy.Themes.ResourceKeys;
Expand All @@ -74,9 +75,9 @@ namespace ICSharpCode.ILSpy.TextView
/// </summary>
public sealed partial class DecompilerTextView : UserControl, IHaveState, IProgress<DecompilationProgress>
{
readonly AssemblyTreeModel assemblyTreeModel;
readonly IExportProvider exportProvider;
readonly SettingsService settingsService;
private readonly LanguageService languageService;
readonly LanguageService languageService;
readonly ReferenceElementGenerator referenceElementGenerator;
readonly UIElementGenerator uiElementGenerator;
readonly List<VisualLineElementGenerator?> activeCustomElementGenerators = new List<VisualLineElementGenerator?>();
Expand All @@ -97,11 +98,11 @@ public sealed partial class DecompilerTextView : UserControl, IHaveState, IProgr
readonly List<ITextMarker> localReferenceMarks = new List<ITextMarker>();

#region Constructor
public DecompilerTextView(TabPageModel tabPage)
public DecompilerTextView(IExportProvider exportProvider)
{
this.assemblyTreeModel = tabPage.AssemblyTreeModel;
this.settingsService = tabPage.SettingsService;
this.languageService = tabPage.LanguageService;
this.exportProvider = exportProvider;
settingsService = exportProvider.GetExportedValue<SettingsService>();
languageService = exportProvider.GetExportedValue<LanguageService>();

RegisterHighlighting();

Expand Down Expand Up @@ -433,7 +434,8 @@ void ToolTipClosed(object? sender, EventArgs e)
}
else if (segment.Reference is EntityReference unresolvedEntity)
{
var module = unresolvedEntity.ResolveAssembly(assemblyTreeModel.AssemblyList);
var assemblyList = exportProvider.GetExportedValue<AssemblyList>();
var module = unresolvedEntity.ResolveAssembly(assemblyList);
if (module == null)
return null;
var typeSystem = new DecompilerTypeSystem(module,
Expand Down Expand Up @@ -493,7 +495,8 @@ void ToolTipClosed(object? sender, EventArgs e)

IEntity? ResolveReference(string idString)
{
return AssemblyTreeModel.FindEntityInRelevantAssemblies(idString, assemblyTreeModel.AssemblyList.GetAssemblies());
var assemblyList = exportProvider.GetExportedValue<AssemblyList>();
return AssemblyTreeModel.FindEntityInRelevantAssemblies(idString, assemblyList.GetAssemblies());
}
}

Expand Down
Loading

0 comments on commit 8ad35c4

Please sign in to comment.