Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace singletons with DI patterns... #3314

Merged
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Get rid of singletons, replace with DI: MainWindow, Settings and Lang…
…uage service
tom-englert committed Oct 26, 2024
commit 560d89a42fdad2b1b91f357a77562f919166649a
6 changes: 4 additions & 2 deletions ILSpy.ReadyToRun/ReadyToRunDisassembler.cs
Original file line number Diff line number Diff line change
@@ -38,20 +38,22 @@ internal class ReadyToRunDisassembler
private readonly ITextOutput output;
private readonly ReadyToRunReader reader;
private readonly RuntimeFunction runtimeFunction;
private readonly SettingsService settingsService;

public ReadyToRunDisassembler(ITextOutput output, ReadyToRunReader reader, RuntimeFunction runtimeFunction)
public ReadyToRunDisassembler(ITextOutput output, ReadyToRunReader reader, RuntimeFunction runtimeFunction, SettingsService settingsService)
{
this.output = output;
this.reader = reader;
this.runtimeFunction = runtimeFunction;
this.settingsService = settingsService;
}

public void Disassemble(PEFile currentFile, int bitness, ulong address, bool showMetadataTokens, bool showMetadataTokensInBase10)
{
ReadyToRunMethod readyToRunMethod = runtimeFunction.Method;
WriteCommentLine(readyToRunMethod.SignatureString);

var options = SettingsService.Instance.GetSettings<ReadyToRunOptions>();
var options = settingsService.GetSettings<ReadyToRunOptions>();

if (options.IsShowGCInfo)
{
12 changes: 8 additions & 4 deletions ILSpy.ReadyToRun/ReadyToRunLanguage.cs
Original file line number Diff line number Diff line change
@@ -38,6 +38,10 @@

using ILCompiler.Reflection.ReadyToRun;

using TomsToolbox.Composition;

using MetadataReader = System.Reflection.Metadata.MetadataReader;

namespace ICSharpCode.ILSpy.ReadyToRun
{
#if STRESS
@@ -97,7 +101,7 @@ public void WriteReference(IMember member, string text, bool isDefinition = fals

[Export(typeof(Language))]
[Shared]
internal class ReadyToRunLanguage : Language
internal class ReadyToRunLanguage(SettingsService settingsService, IExportProvider exportProvider) : Language
{
private static readonly ConditionalWeakTable<MetadataFile, ReadyToRunReaderCacheEntry> readyToRunReaders = new ConditionalWeakTable<MetadataFile, ReadyToRunReaderCacheEntry>();

@@ -175,7 +179,7 @@ public override void DecompileMethod(IMethod method, ITextOutput output, Decompi
.GroupBy(m => m.MethodHandle)
.ToDictionary(g => g.Key, g => g.ToArray());
}
var displaySettings = SettingsService.Instance.DisplaySettings;
var displaySettings = settingsService.DisplaySettings;
bool showMetadataTokens = displaySettings.ShowMetadataTokens;
bool showMetadataTokensInBase10 = displaySettings.ShowMetadataTokensInBase10;
#if STRESS
@@ -205,7 +209,7 @@ public override void DecompileMethod(IMethod method, ITextOutput output, Decompi
file = ((IlSpyAssemblyMetadata)readyToRunMethod.ComponentReader).Module;
}

new ReadyToRunDisassembler(output, disassemblingReader, runtimeFunction).Disassemble(file, bitness, (ulong)runtimeFunction.StartAddress, showMetadataTokens, showMetadataTokensInBase10);
new ReadyToRunDisassembler(output, disassemblingReader, runtimeFunction, settingsService).Disassemble(file, bitness, (ulong)runtimeFunction.StartAddress, showMetadataTokens, showMetadataTokensInBase10);
}
}
}
@@ -218,7 +222,7 @@ public override void DecompileMethod(IMethod method, ITextOutput output, Decompi

public override RichText GetRichTextTooltip(IEntity entity)
{
return LanguageService.Instance.ILLanguage.GetRichTextTooltip(entity);
return exportProvider.GetExportedValue<LanguageService>().ILLanguage.GetRichTextTooltip(entity);
}

private ReadyToRunReaderCacheEntry GetReader(LoadedAssembly assembly, MetadataFile file)
Original file line number Diff line number Diff line change
@@ -145,7 +145,7 @@ public void VerifyReturnsOnlyInterfaceMembers()
var analyzer = new MemberImplementsInterfaceAnalyzer();

// Act
var results = analyzer.Analyze(symbol, new AnalyzerContext() { AssemblyList = new ILSpyX.AssemblyList(), Language = new CSharpLanguage([]) });
var results = analyzer.Analyze(symbol, new AnalyzerContext() { AssemblyList = new ILSpyX.AssemblyList(), Language = new CSharpLanguage() });

// Assert
Assert.That(results, Is.Not.Null);
2 changes: 1 addition & 1 deletion ILSpy.Tests/Analyzers/MethodUsesAnalyzerTests.cs
Original file line number Diff line number Diff line change
@@ -30,7 +30,7 @@ public void Setup()
testAssembly = assemblyList.OpenAssembly(typeof(MethodUsesAnalyzerTests).Assembly.Location);
assemblyList.OpenAssembly(typeof(void).Assembly.Location);
testAssemblyTypeSystem = testAssembly.GetTypeSystemOrNull();
language = new CSharpLanguage([]);
language = new CSharpLanguage();
typeDefinition = testAssemblyTypeSystem.FindType(typeof(TestCases.Main.MainAssembly)).GetDefinition();
}

2 changes: 1 addition & 1 deletion ILSpy.Tests/Analyzers/TypeUsedByAnalyzerTests.cs
Original file line number Diff line number Diff line change
@@ -41,7 +41,7 @@ public void Setup()
assemblyList = new AssemblyList();
testAssembly = assemblyList.OpenAssembly(typeof(MethodUsesAnalyzerTests).Assembly.Location);
testAssemblyTypeSystem = new DecompilerTypeSystem(testAssembly.GetMetadataFileOrNull(), testAssembly.GetAssemblyResolver());
language = new CSharpLanguage([]);
language = new CSharpLanguage();
}

[Test]
15 changes: 11 additions & 4 deletions ILSpy/AboutPage.cs
Original file line number Diff line number Diff line change
@@ -17,6 +17,7 @@
// DEALINGS IN THE SOFTWARE.

using System;
using System.Collections.Generic;
using System.Composition;
using System.IO;
using System.Text.RegularExpressions;
@@ -28,6 +29,7 @@

using ICSharpCode.AvalonEdit.Rendering;
using ICSharpCode.Decompiler;
using ICSharpCode.ILSpy.AssemblyTree;
using ICSharpCode.ILSpy.Properties;
using ICSharpCode.ILSpy.TextView;
using ICSharpCode.ILSpy.Themes;
@@ -38,17 +40,22 @@ namespace ICSharpCode.ILSpy
{
[ExportMainMenuCommand(ParentMenuID = nameof(Resources._Help), Header = nameof(Resources._About), MenuOrder = 99999)]
[Shared]
sealed class AboutPage : SimpleCommand
public sealed class AboutPageCommand(AssemblyTreeModel assemblyTreeModel) : SimpleCommand
{
public override void Execute(object parameter)
{
MainWindow.Instance.AssemblyTreeModel.NavigateTo(
assemblyTreeModel.NavigateTo(
new RequestNavigateEventArgs(new Uri("resource://aboutpage"), null),
inNewTabPage: true
);
}
}

public static void Display(DecompilerTextView textView)
[Export]
[Shared]
public sealed class AboutPage(IEnumerable<IAboutPageAddition> aboutPageAdditions)
{
public void Display(DecompilerTextView textView)
{
AvalonEditTextOutput output = new AvalonEditTextOutput() {
Title = Resources.About,
@@ -86,7 +93,7 @@ public static void Display(DecompilerTextView textView)
});
output.WriteLine();

foreach (var plugin in App.ExportProvider.GetExportedValues<IAboutPageAddition>())
foreach (var plugin in aboutPageAdditions)
plugin.Write(output);
output.WriteLine();
output.Address = new Uri("resource://AboutPage");
21 changes: 10 additions & 11 deletions ILSpy/Analyzers/AnalyzeCommand.cs
Original file line number Diff line number Diff line change
@@ -20,17 +20,18 @@
using System.Linq;

using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.AssemblyTree;
using ICSharpCode.ILSpy.Properties;
using ICSharpCode.ILSpy.TreeNodes;

using TomsToolbox.Composition;

namespace ICSharpCode.ILSpy.Analyzers
{
[ExportContextMenuEntry(Header = nameof(Resources.Analyze), Icon = "Images/Search", Category = nameof(Resources.Analyze), InputGestureText = "Ctrl+R", Order = 100)]
[Shared]
internal sealed class AnalyzeContextMenuCommand : IContextMenuEntry
internal sealed class AnalyzeContextMenuCommand(AnalyzerTreeViewModel analyzerTreeView) : IContextMenuEntry
{
private static readonly AnalyzerTreeViewModel AnalyzerTreeView = App.ExportProvider.GetExportedValue<AnalyzerTreeViewModel>();

public bool IsVisible(TextViewContext context)
{
if (context.TreeView is AnalyzerTreeView && context.SelectedTreeNodes != null && context.SelectedTreeNodes.All(n => n.Parent.IsRoot))
@@ -62,30 +63,28 @@ public void Execute(TextViewContext context)
{
foreach (var node in context.SelectedTreeNodes.OfType<IMemberTreeNode>().ToArray())
{
AnalyzerTreeView.Analyze(node.Member);
analyzerTreeView.Analyze(node.Member);
}
}
else if (context.Reference is { Reference: IEntity entity })
{
AnalyzerTreeView.Analyze(entity);
analyzerTreeView.Analyze(entity);
}
}
}

internal sealed class AnalyzeCommand : SimpleCommand
public sealed class AnalyzeCommand(AssemblyTreeModel assemblyTreeModel, AnalyzerTreeViewModel analyzerTreeViewModel) : SimpleCommand
{
private static readonly AnalyzerTreeViewModel AnalyzerTreeView = App.ExportProvider.GetExportedValue<AnalyzerTreeViewModel>();

public override bool CanExecute(object parameter)
{
return MainWindow.Instance.AssemblyTreeModel.SelectedNodes.All(n => n is IMemberTreeNode);
return assemblyTreeModel.SelectedNodes.All(n => n is IMemberTreeNode);
}

public override void Execute(object parameter)
{
foreach (var node in MainWindow.Instance.AssemblyTreeModel.SelectedNodes.OfType<IMemberTreeNode>())
foreach (var node in assemblyTreeModel.SelectedNodes.OfType<IMemberTreeNode>())
{
AnalyzerTreeView.Analyze(node.Member);
analyzerTreeViewModel.Analyze(node.Member);
}
}
}
2 changes: 1 addition & 1 deletion ILSpy/Analyzers/AnalyzerSearchTreeNode.cs
Original file line number Diff line number Diff line change
@@ -61,7 +61,7 @@ protected IEnumerable<AnalyzerTreeNode> FetchChildren(CancellationToken ct)
var context = new AnalyzerContext() {
CancellationToken = ct,
Language = Language,
AssemblyList = MainWindow.Instance.AssemblyTreeModel.AssemblyList
AssemblyList = AssemblyTreeModel.AssemblyList
};
var results = analyzer.Analyze(symbol, context).Select(SymbolTreeNodeFactory);
if (context.SortResults)
14 changes: 13 additions & 1 deletion ILSpy/Analyzers/AnalyzerTreeNode.cs
Original file line number Diff line number Diff line change
@@ -17,15 +17,20 @@
// DEALINGS IN THE SOFTWARE.

using System.Collections.Generic;
using System.Linq;

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

using TomsToolbox.Composition;

namespace ICSharpCode.ILSpy.Analyzers
{
public abstract class AnalyzerTreeNode : SharpTreeNode
{
public Language Language => LanguageService.Instance.Language;
public static Language Language => App.ExportProvider.GetExportedValue<LanguageService>().Language;

public override bool CanDelete()
{
@@ -42,6 +47,13 @@ public override void Delete()
DeleteCore();
}

public static AssemblyTreeModel AssemblyTreeModel { get; } = App.ExportProvider.GetExportedValue<AssemblyTreeModel>();

public static ICollection<IExport<IAnalyzer, IAnalyzerMetadata>> Analyzers => App.ExportProvider
.GetExports<IAnalyzer, IAnalyzerMetadata>("Analyzer")
.OrderBy(item => item.Metadata?.Order)
.ToArray();

/// <summary>
/// Handles changes to the assembly list.
/// </summary>
5 changes: 3 additions & 2 deletions ILSpy/Analyzers/AnalyzerTreeViewModel.cs
Original file line number Diff line number Diff line change
@@ -24,6 +24,7 @@

using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.Analyzers.TreeNodes;
using ICSharpCode.ILSpy.AssemblyTree;
using ICSharpCode.ILSpy.TreeNodes;
using ICSharpCode.ILSpy.ViewModels;

@@ -38,12 +39,12 @@ public class AnalyzerTreeViewModel : ToolPaneModel
{
public const string PaneContentId = "analyzerPane";

public AnalyzerTreeViewModel()
public AnalyzerTreeViewModel(AssemblyTreeModel assemblyTreeModel)
{
ContentId = PaneContentId;
Title = Properties.Resources.Analyze;
ShortcutKey = new(Key.R, ModifierKeys.Control);
AssociatedCommand = ILSpyCommands.Analyze;
AssociatedCommand = new AnalyzeCommand(assemblyTreeModel, this);
}

public AnalyzerRootNode Root { get; } = new();
15 changes: 4 additions & 11 deletions ILSpy/Analyzers/TreeNodes/AnalyzedEventTreeNode.cs
Original file line number Diff line number Diff line change
@@ -17,15 +17,12 @@
// DEALINGS IN THE SOFTWARE.

using System;
using System.Linq;

using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.TreeNodes;

namespace ICSharpCode.ILSpy.Analyzers.TreeNodes
{
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpyX.Analyzers;

internal sealed class AnalyzedEventTreeNode : AnalyzerEntityTreeNode
{
readonly IEvent analyzedEvent;
@@ -54,16 +51,12 @@ protected override void LoadChildren()
if (TryFindBackingField(analyzedEvent, out var backingField))
this.Children.Add(new AnalyzedFieldTreeNode(backingField));

//foreach (var accessor in analyzedEvent.OtherMethods)
// this.Children.Add(new AnalyzedAccessorTreeNode(accessor, null));

var analyzers = App.ExportProvider.GetExports<IAnalyzer, IAnalyzerMetadata>("Analyzer");
foreach (var lazy in analyzers.OrderBy(item => item.Metadata.Order))
foreach (var lazy in Analyzers)
{
var analyzer = lazy.Value;
if (analyzer.Show(analyzedEvent))
{
this.Children.Add(new AnalyzerSearchTreeNode(analyzedEvent, analyzer, lazy.Metadata.Header));
this.Children.Add(new AnalyzerSearchTreeNode(analyzedEvent, analyzer, lazy.Metadata?.Header));
}
}
}
@@ -73,7 +66,7 @@ bool TryFindBackingField(IEvent analyzedEvent, out IField backingField)
backingField = null;
foreach (var field in analyzedEvent.DeclaringTypeDefinition.GetFields(options: GetMemberOptions.IgnoreInheritedMembers))
{
if (field.Name == analyzedEvent.Name && field.Accessibility == Accessibility.Private)
if (field.Name == analyzedEvent.Name && field.Accessibility == Decompiler.TypeSystem.Accessibility.Private)
{
backingField = field;
return true;
7 changes: 2 additions & 5 deletions ILSpy/Analyzers/TreeNodes/AnalyzedFieldTreeNode.cs
Original file line number Diff line number Diff line change
@@ -17,11 +17,9 @@
// DEALINGS IN THE SOFTWARE.

using System;
using System.Linq;

using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.TreeNodes;
using ICSharpCode.ILSpyX.Analyzers;

namespace ICSharpCode.ILSpy.Analyzers.TreeNodes
{
@@ -41,13 +39,12 @@ public AnalyzedFieldTreeNode(IField analyzedField)

protected override void LoadChildren()
{
var analyzers = App.ExportProvider.GetExports<IAnalyzer, IAnalyzerMetadata>("Analyzer");
foreach (var lazy in analyzers.OrderBy(item => item.Metadata.Order))
foreach (var lazy in Analyzers)
{
var analyzer = lazy.Value;
if (analyzer.Show(analyzedField))
{
this.Children.Add(new AnalyzerSearchTreeNode(analyzedField, analyzer, lazy.Metadata.Header));
this.Children.Add(new AnalyzerSearchTreeNode(analyzedField, analyzer, lazy.Metadata?.Header));
}
}
}
5 changes: 1 addition & 4 deletions ILSpy/Analyzers/TreeNodes/AnalyzedMethodTreeNode.cs
Original file line number Diff line number Diff line change
@@ -17,11 +17,9 @@
// DEALINGS IN THE SOFTWARE.

using System;
using System.Linq;

using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.TreeNodes;
using ICSharpCode.ILSpyX.Analyzers;

namespace ICSharpCode.ILSpy.Analyzers.TreeNodes
{
@@ -43,8 +41,7 @@ public AnalyzedMethodTreeNode(IMethod analyzedMethod, string prefix = "")

protected override void LoadChildren()
{
var analyzers = App.ExportProvider.GetExports<IAnalyzer, IAnalyzerMetadata>("Analyzer");
foreach (var lazy in analyzers.OrderBy(item => item.Metadata.Order))
foreach (var lazy in Analyzers)
{
var analyzer = lazy.Value;
if (analyzer.Show(analyzedMethod))
5 changes: 1 addition & 4 deletions ILSpy/Analyzers/TreeNodes/AnalyzedModuleTreeNode.cs
Original file line number Diff line number Diff line change
@@ -17,11 +17,9 @@
// DEALINGS IN THE SOFTWARE.

using System;
using System.Linq;
using System.Windows;

using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpyX.Analyzers;
using ICSharpCode.ILSpyX.TreeView.PlatformAbstractions;

namespace ICSharpCode.ILSpy.Analyzers.TreeNodes
@@ -42,8 +40,7 @@ public AnalyzedModuleTreeNode(IModule analyzedModule)

protected override void LoadChildren()
{
var analyzers = App.ExportProvider.GetExports<IAnalyzer, IAnalyzerMetadata>("Analyzer");
foreach (var lazy in analyzers.OrderBy(item => item.Metadata.Order))
foreach (var lazy in Analyzers)
{
var analyzer = lazy.Value;
if (analyzer.Show(analyzedModule))
Loading