diff --git a/ILSpy.ReadyToRun/ILSpy.ReadyToRun.csproj b/ILSpy.ReadyToRun/ILSpy.ReadyToRun.csproj
index 0232533b1..a1f50dce8 100644
--- a/ILSpy.ReadyToRun/ILSpy.ReadyToRun.csproj
+++ b/ILSpy.ReadyToRun/ILSpy.ReadyToRun.csproj
@@ -3,14 +3,13 @@
ILSpy.ReadyToRun.Plugin
- net10.0-windows
- win-x64;win-arm64
+ net10.0
False
en-US
true
- true
false
- true
+ disable
+ true
@@ -31,16 +30,18 @@
+
+
+
+ So ensure NuGet uses consistent versions (from Directory.Packages.props) for these. -->
diff --git a/ILSpy.ReadyToRun/ReadyToRunDisassembler.cs b/ILSpy.ReadyToRun/ReadyToRunDisassembler.cs
index 5acffa251..d70485ca4 100644
--- a/ILSpy.ReadyToRun/ReadyToRunDisassembler.cs
+++ b/ILSpy.ReadyToRun/ReadyToRunDisassembler.cs
@@ -26,11 +26,12 @@ using Iced.Intel;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.Metadata;
-using ICSharpCode.ILSpy.Util;
using ILCompiler.Reflection.ReadyToRun;
using ILCompiler.Reflection.ReadyToRun.Amd64;
+using ILSpy;
+
namespace ICSharpCode.ILSpy.ReadyToRun
{
internal class ReadyToRunDisassembler
diff --git a/ILSpy.ReadyToRun/ReadyToRunLanguage.cs b/ILSpy.ReadyToRun/ReadyToRunLanguage.cs
index 2b7d084eb..fe7db176f 100644
--- a/ILSpy.ReadyToRun/ReadyToRunLanguage.cs
+++ b/ILSpy.ReadyToRun/ReadyToRunLanguage.cs
@@ -30,18 +30,20 @@ using System.Reflection.PortableExecutable;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
-using ICSharpCode.AvalonEdit.Highlighting;
+using AvaloniaEdit.Highlighting;
+
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.Metadata;
+using ICSharpCode.Decompiler.Output;
using ICSharpCode.Decompiler.Solution;
using ICSharpCode.Decompiler.TypeSystem;
-using ICSharpCode.ILSpy.Util;
using ICSharpCode.ILSpyX;
using ILCompiler.Reflection.ReadyToRun;
-using TomsToolbox.Composition;
+using ILSpy;
+using ILSpy.Languages;
using MetadataReader = System.Reflection.Metadata.MetadataReader;
@@ -108,7 +110,10 @@ namespace ICSharpCode.ILSpy.ReadyToRun
[Export(typeof(Language))]
[Shared]
- internal class ReadyToRunLanguage(SettingsService settingsService, IExportProvider exportProvider) : Language
+ [method: ImportingConstructor]
+ // LanguageService is taken Lazy because it imports Language[] -- a direct LanguageService
+ // dependency creates a constructor-injection cycle that System.Composition refuses.
+ internal class ReadyToRunLanguage(SettingsService settingsService, Lazy languageService) : Language
{
private static readonly ConditionalWeakTable readyToRunReaders = new ConditionalWeakTable();
@@ -229,7 +234,7 @@ namespace ICSharpCode.ILSpy.ReadyToRun
public override RichText GetRichTextTooltip(IEntity entity)
{
- return exportProvider.GetExportedValue().ILLanguage.GetRichTextTooltip(entity);
+ return languageService.Value.GetLanguage("IL").GetRichTextTooltip(entity);
}
private ReadyToRunReaderCacheEntry GetReader(LoadedAssembly assembly, MetadataFile file)
diff --git a/ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml b/ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml
deleted file mode 100644
index 39aa35451..000000000
--- a/ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/ILSpy.ReadyToRun/ReadyToRunOptions.cs b/ILSpy.ReadyToRun/ReadyToRunOptions.cs
index c2b94929c..28c7418a6 100644
--- a/ILSpy.ReadyToRun/ReadyToRunOptions.cs
+++ b/ILSpy.ReadyToRun/ReadyToRunOptions.cs
@@ -18,13 +18,13 @@
using System.Xml.Linq;
-using ICSharpCode.ILSpyX.Settings;
+using CommunityToolkit.Mvvm.ComponentModel;
-using TomsToolbox.Wpf;
+using ICSharpCode.ILSpyX.Settings;
namespace ICSharpCode.ILSpy.ReadyToRun
{
- internal partial class ReadyToRunOptions : ObservableObjectBase, ISettingsSection
+ internal partial class ReadyToRunOptions : ObservableObject, ISettingsSection
{
private static readonly XNamespace ns = "http://www.ilspy.net/ready-to-run";
diff --git a/ILSpy.ReadyToRun/ReadyToRunOptionsView.axaml b/ILSpy.ReadyToRun/ReadyToRunOptionsView.axaml
new file mode 100644
index 000000000..eafd12fa6
--- /dev/null
+++ b/ILSpy.ReadyToRun/ReadyToRunOptionsView.axaml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ILSpy.ReadyToRun/ReadyToRunOptionsView.axaml.cs b/ILSpy.ReadyToRun/ReadyToRunOptionsView.axaml.cs
new file mode 100644
index 000000000..d2be1a370
--- /dev/null
+++ b/ILSpy.ReadyToRun/ReadyToRunOptionsView.axaml.cs
@@ -0,0 +1,33 @@
+// Copyright (c) 2018 Siegfried Pammer
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this
+// software and associated documentation files (the "Software"), to deal in the Software
+// without restriction, including without limitation the rights to use, copy, modify, merge,
+// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
+// to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or
+// substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
+// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+using global::Avalonia.Controls;
+using global::Avalonia.Markup.Xaml;
+
+namespace ICSharpCode.ILSpy.ReadyToRun
+{
+ public partial class ReadyToRunOptionsView : UserControl
+ {
+ public ReadyToRunOptionsView()
+ {
+ InitializeComponent();
+ }
+
+ void InitializeComponent() => AvaloniaXamlLoader.Load(this);
+ }
+}
diff --git a/ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml.cs b/ILSpy.ReadyToRun/ReadyToRunOptionsViewModel.cs
similarity index 66%
rename from ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml.cs
rename to ILSpy.ReadyToRun/ReadyToRunOptionsViewModel.cs
index bb4c6d440..b25eee314 100644
--- a/ILSpy.ReadyToRun/ReadyToRunOptionPage.xaml.cs
+++ b/ILSpy.ReadyToRun/ReadyToRunOptionsViewModel.cs
@@ -1,14 +1,14 @@
// Copyright (c) 2018 Siegfried Pammer
-//
+//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
-//
+//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
-//
+//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
@@ -17,46 +17,32 @@
// DEALINGS IN THE SOFTWARE.
using System.Composition;
+using System.Xml.Linq;
-using ICSharpCode.ILSpy.Options;
-using ICSharpCode.ILSpy.Util;
+using CommunityToolkit.Mvvm.ComponentModel;
-using TomsToolbox.Wpf;
-using TomsToolbox.Wpf.Composition.AttributedModel;
+using ILSpy;
+using ILSpy.Options;
namespace ICSharpCode.ILSpy.ReadyToRun
{
- [DataTemplate(typeof(ReadyToRunOptionsViewModel))]
- [NonShared]
- partial class ReadyToRunOptionPage
- {
- public ReadyToRunOptionPage()
- {
- InitializeComponent();
- }
- }
-
[ExportOptionPage(Order = 40)]
- [NonShared]
- class ReadyToRunOptionsViewModel : ObservableObjectBase, IOptionPage
+ [Shared]
+ internal sealed partial class ReadyToRunOptionsViewModel : ObservableObject, IOptionPage
{
- private ReadyToRunOptions options;
-
- public ReadyToRunOptions Options {
- get => options;
- set => SetProperty(ref options, value);
- }
+ [ObservableProperty]
+ ReadyToRunOptions options = null!;
public string Title => global::ILSpy.ReadyToRun.Properties.Resources.ReadyToRun;
- public void Load(SettingsSnapshot snapshot)
+ public void Load(SettingsService service)
{
- Options = snapshot.GetSettings();
+ Options = service.GetSettings();
}
public void LoadDefaults()
{
- Options.LoadFromXml(new("empty"));
+ Options.LoadFromXml(new XElement("ReadyToRunOptions"));
}
}
-}
\ No newline at end of file
+}
diff --git a/ILSpy.sln b/ILSpy.sln
index 954caa09e..6f7d6b923 100644
--- a/ILSpy.sln
+++ b/ILSpy.sln
@@ -1,3 +1,4 @@
+
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 18
VisualStudioVersion = 18.4.11620.152
@@ -38,6 +39,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ILSpy.Tests", "ILSpy.Tests\
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ILSpy.Tests.Windows", "ILSpy.Tests.Windows\ILSpy.Tests.Windows.csproj", "{20AF56FB-DC0F-4048-B75D-83FEE0D669B2}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ILSpy.ReadyToRun", "ILSpy.ReadyToRun\ILSpy.ReadyToRun.csproj", "{AF43A431-AAF7-4758-A180-42C378AE0FB2}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -168,6 +171,18 @@ Global
{20AF56FB-DC0F-4048-B75D-83FEE0D669B2}.Release|x64.Build.0 = Release|Any CPU
{20AF56FB-DC0F-4048-B75D-83FEE0D669B2}.Release|x86.ActiveCfg = Release|Any CPU
{20AF56FB-DC0F-4048-B75D-83FEE0D669B2}.Release|x86.Build.0 = Release|Any CPU
+ {AF43A431-AAF7-4758-A180-42C378AE0FB2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {AF43A431-AAF7-4758-A180-42C378AE0FB2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AF43A431-AAF7-4758-A180-42C378AE0FB2}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {AF43A431-AAF7-4758-A180-42C378AE0FB2}.Debug|x64.Build.0 = Debug|Any CPU
+ {AF43A431-AAF7-4758-A180-42C378AE0FB2}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {AF43A431-AAF7-4758-A180-42C378AE0FB2}.Debug|x86.Build.0 = Debug|Any CPU
+ {AF43A431-AAF7-4758-A180-42C378AE0FB2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {AF43A431-AAF7-4758-A180-42C378AE0FB2}.Release|Any CPU.Build.0 = Release|Any CPU
+ {AF43A431-AAF7-4758-A180-42C378AE0FB2}.Release|x64.ActiveCfg = Release|Any CPU
+ {AF43A431-AAF7-4758-A180-42C378AE0FB2}.Release|x64.Build.0 = Release|Any CPU
+ {AF43A431-AAF7-4758-A180-42C378AE0FB2}.Release|x86.ActiveCfg = Release|Any CPU
+ {AF43A431-AAF7-4758-A180-42C378AE0FB2}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/ILSpy/ViewLocator.cs b/ILSpy/ViewLocator.cs
index ecdb22c2d..6c9287a92 100644
--- a/ILSpy/ViewLocator.cs
+++ b/ILSpy/ViewLocator.cs
@@ -28,6 +28,7 @@ using Dock.Model.Core;
using ILSpy.Analyzers;
using ILSpy.AssemblyTree;
using ILSpy.Compare;
+using ILSpy.Options;
using ILSpy.Search;
using ILSpy.TextView;
using ILSpy.ViewModels;
@@ -77,9 +78,21 @@ namespace ILSpy
return null;
if (s_views.TryGetValue(param.GetType(), out var ctor))
return ctor();
- // Convention fallback for ViewModelBase-derived VMs not in the explicit map.
+ // Convention fallback: SomeViewModel -> SomeView. Type.GetType only searches the
+ // calling assembly + corelib, so a plugin viewmodel (loaded into the AppDomain
+ // at runtime by AppComposition.LoadPlugins) wouldn't be found via that path
+ // alone. Walk every loaded assembly to find the matching View type.
var name = param.GetType().FullName!.Replace("ViewModel", "View", StringComparison.Ordinal);
var type = Type.GetType(name);
+ if (type == null)
+ {
+ foreach (var asm in AppDomain.CurrentDomain.GetAssemblies())
+ {
+ type = asm.GetType(name);
+ if (type != null)
+ break;
+ }
+ }
if (type != null)
return (Control)Activator.CreateInstance(type)!;
return new TextBlock { Text = "Not Found: " + name };
@@ -91,6 +104,7 @@ namespace ILSpy
return false;
return data is IDockable
|| data is ViewModelBase
+ || data is IOptionPage
|| s_views.ContainsKey(data.GetType());
}
}