From cb6b88a3eeaa12aa473d7a6e94a5d85ee75e1e57 Mon Sep 17 00:00:00 2001 From: Aleksandr Nikolaev Date: Thu, 2 Jul 2026 16:43:22 +0300 Subject: [PATCH] Upgraded to support Avalonia v12.0.1 --- build/AvaloniaDependency.props | 4 +- build/Base.props | 2 +- build/BuildTargets.props | 2 +- build/Nuget.props | 5 +- build/SampleApp.props | 14 +- .../BootstrapperShellSample.csproj | 3 +- .../Views/MainWindow.axaml.cs | 2 +- samples/DummyModule1/DummyModule1.csproj | 2 +- samples/DummyModule2/DummyModule2.csproj | 2 +- .../ModulesSample.Infrastructure.csproj | 2 +- samples/ModulesSample/MainWindow.axaml.cs | 2 +- samples/ModulesSample/ModulesSampleApp.csproj | 2 +- .../SampleDialogApp/SampleDialogApp.csproj | 3 +- .../SampleDialogApp/Views/MainWindow.axaml.cs | 4 +- samples/SampleMvvmApp/SampleMvvmApp.csproj | 3 +- .../SampleMvvmApp/Views/MainWindow.axaml.cs | 2 +- samples/ViewDiscovery/ViewDiscovery.csproj | 3 +- .../ViewDiscovery/Views/MainWindow.axaml.cs | 2 +- ...g.netcore.cs => DirectoryModuleCatalog.cs} | 2 +- .../DirectoryModuleCatalog.net45.cs | 247 ------------------ src/Prism.Avalonia/Prism.Avalonia.csproj | 15 +- .../Prism.DryIoc.Avalonia.csproj | 2 +- .../Prism.Avalonia.Tests.csproj | 11 +- 23 files changed, 42 insertions(+), 294 deletions(-) rename src/Prism.Avalonia/Modularity/{DirectoryModuleCatalog.netcore.cs => DirectoryModuleCatalog.cs} (99%) delete mode 100644 src/Prism.Avalonia/Modularity/DirectoryModuleCatalog.net45.cs diff --git a/build/AvaloniaDependency.props b/build/AvaloniaDependency.props index f6e537b..f374770 100644 --- a/build/AvaloniaDependency.props +++ b/build/AvaloniaDependency.props @@ -2,8 +2,8 @@ - - + + diff --git a/build/Base.props b/build/Base.props index 722bbf3..990e711 100644 --- a/build/Base.props +++ b/build/Base.props @@ -2,7 +2,7 @@ - 8.1.97.11073 + 8.1.97.12000-pre https://github.com/AvaloniaCommunity/Prism.Avalonia Copyright (c) 2024 Xeno Innovations, Inc. MIT diff --git a/build/BuildTargets.props b/build/BuildTargets.props index 9a5c75e..a90821f 100644 --- a/build/BuildTargets.props +++ b/build/BuildTargets.props @@ -3,7 +3,7 @@ xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - netstandard2.0;netstandard2.1;net6.0;net7.0;net8.0 + net8.0;net9.0;net10.0 diff --git a/build/Nuget.props b/build/Nuget.props index 1496a1b..b8882bb 100644 --- a/build/Nuget.props +++ b/build/Nuget.props @@ -6,9 +6,8 @@ true false - * Added .NET 8 support - * Upgraded to support Avalonia v11.0.7 - * Removed unused CommonServiceLocator + * Dropped support for .NET Framework and .NET Standard. Only .NET 8 and later are supported + * Upgraded to support Avalonia v12.0.1 diff --git a/build/SampleApp.props b/build/SampleApp.props index f06c124..b883a5b 100644 --- a/build/SampleApp.props +++ b/build/SampleApp.props @@ -6,12 +6,14 @@ - - - - - - + + + + + + + + diff --git a/samples/BootstrapperShellSample/BootstrapperShellSample.csproj b/samples/BootstrapperShellSample/BootstrapperShellSample.csproj index 7ddf729..b941d9b 100644 --- a/samples/BootstrapperShellSample/BootstrapperShellSample.csproj +++ b/samples/BootstrapperShellSample/BootstrapperShellSample.csproj @@ -1,8 +1,9 @@  Exe - net6.0;net7.0;net8.0 + net8.0;net9.0;net10.0 Damian Suess + false diff --git a/samples/BootstrapperShellSample/Views/MainWindow.axaml.cs b/samples/BootstrapperShellSample/Views/MainWindow.axaml.cs index ac4fdfd..8d6ed7a 100644 --- a/samples/BootstrapperShellSample/Views/MainWindow.axaml.cs +++ b/samples/BootstrapperShellSample/Views/MainWindow.axaml.cs @@ -12,7 +12,7 @@ public partial class MainWindow : Window public MainWindow() { this.InitializeComponent(); - this.AttachDevTools(); + //this.AttachDevTools(); } } } diff --git a/samples/DummyModule1/DummyModule1.csproj b/samples/DummyModule1/DummyModule1.csproj index d3c2810..32ef456 100644 --- a/samples/DummyModule1/DummyModule1.csproj +++ b/samples/DummyModule1/DummyModule1.csproj @@ -1,7 +1,7 @@  - net6.0;net7.0;net8.0 + net8.0;net9.0;net10.0 Damian Suess diff --git a/samples/DummyModule2/DummyModule2.csproj b/samples/DummyModule2/DummyModule2.csproj index 54a5b0f..e20cbc2 100644 --- a/samples/DummyModule2/DummyModule2.csproj +++ b/samples/DummyModule2/DummyModule2.csproj @@ -1,7 +1,7 @@  - net6.0;net7.0;net8.0 + net8.0;net9.0;net10.0 Damian Suess diff --git a/samples/ModulesSample.Infrastructure/ModulesSample.Infrastructure.csproj b/samples/ModulesSample.Infrastructure/ModulesSample.Infrastructure.csproj index 5303810..d272189 100644 --- a/samples/ModulesSample.Infrastructure/ModulesSample.Infrastructure.csproj +++ b/samples/ModulesSample.Infrastructure/ModulesSample.Infrastructure.csproj @@ -1,7 +1,7 @@  - net6.0;net7.0;net8.0 + net8.0;net9.0;net10.0 Damian Suess diff --git a/samples/ModulesSample/MainWindow.axaml.cs b/samples/ModulesSample/MainWindow.axaml.cs index ad28aa7..5138189 100644 --- a/samples/ModulesSample/MainWindow.axaml.cs +++ b/samples/ModulesSample/MainWindow.axaml.cs @@ -24,7 +24,7 @@ public MainWindow(IEventAggregator eventAggregator) ////public MainWindow(CallbackLogger logger, IEventAggregator eventAggregator) { InitializeComponent(); - this.AttachDevTools(); + //this.AttachDevTools(); _logTextBox = this.FindControl("LogTextBox"); _itemsControl = this.FindControl("ItemsControl1"); diff --git a/samples/ModulesSample/ModulesSampleApp.csproj b/samples/ModulesSample/ModulesSampleApp.csproj index 6a52809..0238c53 100644 --- a/samples/ModulesSample/ModulesSampleApp.csproj +++ b/samples/ModulesSample/ModulesSampleApp.csproj @@ -1,7 +1,7 @@  Exe - net6.0;net7.0;net8.0 + net8.0;net9.0;net10.0 Damian Suess diff --git a/samples/SampleDialogApp/SampleDialogApp.csproj b/samples/SampleDialogApp/SampleDialogApp.csproj index 0f96af5..51d2d9b 100644 --- a/samples/SampleDialogApp/SampleDialogApp.csproj +++ b/samples/SampleDialogApp/SampleDialogApp.csproj @@ -1,12 +1,13 @@  WinExe - net6.0;net7.0;net8.0 + net8.0;net9.0;net10.0 enable copyused Damian Suess true + false diff --git a/samples/SampleDialogApp/Views/MainWindow.axaml.cs b/samples/SampleDialogApp/Views/MainWindow.axaml.cs index d9966c4..344da56 100644 --- a/samples/SampleDialogApp/Views/MainWindow.axaml.cs +++ b/samples/SampleDialogApp/Views/MainWindow.axaml.cs @@ -1,4 +1,4 @@ -using Avalonia; +using Avalonia; using Avalonia.Controls; using Avalonia.Markup.Xaml; @@ -10,7 +10,7 @@ public MainWindow() { InitializeComponent(); #if DEBUG - this.AttachDevTools(); + //this.AttachDevTools(); #endif } diff --git a/samples/SampleMvvmApp/SampleMvvmApp.csproj b/samples/SampleMvvmApp/SampleMvvmApp.csproj index d465a02..2113069 100644 --- a/samples/SampleMvvmApp/SampleMvvmApp.csproj +++ b/samples/SampleMvvmApp/SampleMvvmApp.csproj @@ -1,9 +1,10 @@  WinExe - net6.0;net7.0;net8.0 + net8.0;net9.0;net10.0 Damian Suess Sample MVVM App + false diff --git a/samples/SampleMvvmApp/Views/MainWindow.axaml.cs b/samples/SampleMvvmApp/Views/MainWindow.axaml.cs index fd6ca64..919ea30 100644 --- a/samples/SampleMvvmApp/Views/MainWindow.axaml.cs +++ b/samples/SampleMvvmApp/Views/MainWindow.axaml.cs @@ -9,7 +9,7 @@ public MainWindow() { InitializeComponent(); #if DEBUG - this.AttachDevTools(); + //this.AttachDevTools(); #endif // Avalonia v11-Preview 5 Breaking Change: diff --git a/samples/ViewDiscovery/ViewDiscovery.csproj b/samples/ViewDiscovery/ViewDiscovery.csproj index bb5b87b..d4f93f6 100644 --- a/samples/ViewDiscovery/ViewDiscovery.csproj +++ b/samples/ViewDiscovery/ViewDiscovery.csproj @@ -1,8 +1,9 @@  WinExe - net6.0;net7.0;net8.0 + net8.0;net9.0;net10.0 Damian Suess + false diff --git a/samples/ViewDiscovery/Views/MainWindow.axaml.cs b/samples/ViewDiscovery/Views/MainWindow.axaml.cs index 5ef86c7..2122f9d 100644 --- a/samples/ViewDiscovery/Views/MainWindow.axaml.cs +++ b/samples/ViewDiscovery/Views/MainWindow.axaml.cs @@ -21,7 +21,7 @@ public MainWindow() public MainWindow(IRegionManager regionManager) { this.InitializeComponent(); - this.AttachDevTools(); + //this.AttachDevTools(); _regionManager = regionManager; regionManager.RegisterViewWithRegion(RegionNames.ContentRegion, typeof(ViewA)); diff --git a/src/Prism.Avalonia/Modularity/DirectoryModuleCatalog.netcore.cs b/src/Prism.Avalonia/Modularity/DirectoryModuleCatalog.cs similarity index 99% rename from src/Prism.Avalonia/Modularity/DirectoryModuleCatalog.netcore.cs rename to src/Prism.Avalonia/Modularity/DirectoryModuleCatalog.cs index fd6693f..5c28521 100644 --- a/src/Prism.Avalonia/Modularity/DirectoryModuleCatalog.netcore.cs +++ b/src/Prism.Avalonia/Modularity/DirectoryModuleCatalog.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Globalization; diff --git a/src/Prism.Avalonia/Modularity/DirectoryModuleCatalog.net45.cs b/src/Prism.Avalonia/Modularity/DirectoryModuleCatalog.net45.cs deleted file mode 100644 index d4c3465..0000000 --- a/src/Prism.Avalonia/Modularity/DirectoryModuleCatalog.net45.cs +++ /dev/null @@ -1,247 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Security.Policy; -using Prism.Properties; - -namespace Prism.Modularity -{ - /// - /// Represets a catalog created from a directory on disk. - /// - /// - /// The directory catalog will scan the contents of a directory, locating classes that implement - /// and add them to the catalog based on contents in their associated . - /// Assemblies are loaded into a new application domain with ReflectionOnlyLoad. The application domain is destroyed - /// once the assemblies have been discovered. - /// - /// The diretory catalog does not continue to monitor the directory after it has created the initialze catalog. - /// - public class DirectoryModuleCatalog : ModuleCatalog - { - /// - /// Directory containing modules to search for. - /// - public string ModulePath { get; set; } - - /// - /// Drives the main logic of building the child domain and searching for the assemblies. - /// - protected override void InnerLoad() - { - if (string.IsNullOrEmpty(this.ModulePath)) - throw new InvalidOperationException(Resources.ModulePathCannotBeNullOrEmpty); - - if (!Directory.Exists(this.ModulePath)) - throw new InvalidOperationException( - string.Format(CultureInfo.CurrentCulture, Resources.DirectoryNotFound, this.ModulePath)); - - AppDomain childDomain = this.BuildChildDomain(AppDomain.CurrentDomain); - - try - { - List loadedAssemblies = new List(); - - var assemblies = ( - from Assembly assembly in AppDomain.CurrentDomain.GetAssemblies() - where !(assembly is System.Reflection.Emit.AssemblyBuilder) - && assembly.GetType().FullName != "System.Reflection.Emit.InternalAssemblyBuilder" - // TODO: Do this in a less hacky way... probably never gonna happen - && !assembly.GetName().Name.StartsWith("xunit") - && !string.IsNullOrEmpty(assembly.Location) - select assembly.Location - ); - - loadedAssemblies.AddRange(assemblies); - - Type loaderType = typeof(InnerModuleInfoLoader); - - if (loaderType.Assembly != null) - { - var loader = - (InnerModuleInfoLoader) - childDomain.CreateInstanceFrom(loaderType.Assembly.Location, loaderType.FullName).Unwrap(); - loader.LoadAssemblies(loadedAssemblies); - this.Items.AddRange(loader.GetModuleInfos(this.ModulePath)); - } - } - finally - { - AppDomain.Unload(childDomain); - } - } - - - /// - /// Creates a new child domain and copies the evidence from a parent domain. - /// - /// The parent domain. - /// The new child domain. - /// - /// Grabs the evidence and uses it to construct the new - /// because in a ClickOnce execution environment, creating an - /// will by default pick up the partial trust environment of - /// the AppLaunch.exe, which was the root executable. The AppLaunch.exe does a - /// create domain and applies the evidence from the ClickOnce manifests to - /// create the domain that the application is actually executing in. This will - /// need to be Full Trust for Prism applications. - /// - /// An is thrown if is null. - protected virtual AppDomain BuildChildDomain(AppDomain parentDomain) - { - if (parentDomain == null) - throw new ArgumentNullException(nameof(parentDomain)); - - Evidence evidence = new Evidence(parentDomain.Evidence); - AppDomainSetup setup = parentDomain.SetupInformation; - return AppDomain.CreateDomain("DiscoveryRegion", evidence, setup); - } - - private class InnerModuleInfoLoader : MarshalByRefObject - { - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")] - internal ModuleInfo[] GetModuleInfos(string path) - { - DirectoryInfo directory = new DirectoryInfo(path); - - ResolveEventHandler resolveEventHandler = - delegate (object sender, ResolveEventArgs args) { return OnReflectionOnlyResolve(args, directory); }; - - AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += resolveEventHandler; - - Assembly moduleReflectionOnlyAssembly = - AppDomain.CurrentDomain.ReflectionOnlyGetAssemblies().First( - asm => asm.FullName == typeof(IModule).Assembly.FullName); - Type IModuleType = moduleReflectionOnlyAssembly.GetType(typeof(IModule).FullName); - - IEnumerable modules = GetNotAlreadyLoadedModuleInfos(directory, IModuleType); - - var array = modules.ToArray(); - AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve -= resolveEventHandler; - return array; - } - - private static IEnumerable GetNotAlreadyLoadedModuleInfos(DirectoryInfo directory, Type IModuleType) - { - List validAssemblies = new List(); - Assembly[] alreadyLoadedAssemblies = AppDomain.CurrentDomain.ReflectionOnlyGetAssemblies(); - - var fileInfos = directory.GetFiles("*.dll") - .Where(file => alreadyLoadedAssemblies - .FirstOrDefault( - assembly => - String.Compare(Path.GetFileName(assembly.Location), file.Name, - StringComparison.OrdinalIgnoreCase) == 0) == null); - - foreach (FileInfo fileInfo in fileInfos) - { - try - { - Assembly.ReflectionOnlyLoadFrom(fileInfo.FullName); - validAssemblies.Add(fileInfo); - } - catch (BadImageFormatException) - { - // skip non-.NET Dlls - } - } - - return validAssemblies.SelectMany(file => Assembly.ReflectionOnlyLoadFrom(file.FullName) - .GetExportedTypes() - .Where(IModuleType.IsAssignableFrom) - .Where(t => t != IModuleType) - .Where(t => !t.IsAbstract) - .Select(type => CreateModuleInfo(type))); - } - - private static Assembly OnReflectionOnlyResolve(ResolveEventArgs args, DirectoryInfo directory) - { - Assembly loadedAssembly = AppDomain.CurrentDomain.ReflectionOnlyGetAssemblies().FirstOrDefault( - asm => string.Equals(asm.FullName, args.Name, StringComparison.OrdinalIgnoreCase)); - if (loadedAssembly != null) - { - return loadedAssembly; - } - AssemblyName assemblyName = new AssemblyName(args.Name); - string dependentAssemblyFilename = Path.Combine(directory.FullName, assemblyName.Name + ".dll"); - if (File.Exists(dependentAssemblyFilename)) - { - return Assembly.ReflectionOnlyLoadFrom(dependentAssemblyFilename); - } - return Assembly.ReflectionOnlyLoad(args.Name); - } - - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")] - internal void LoadAssemblies(IEnumerable assemblies) - { - foreach (string assemblyPath in assemblies) - { - try - { - Assembly.ReflectionOnlyLoadFrom(assemblyPath); - } - catch (FileNotFoundException) - { - // Continue loading assemblies even if an assembly can not be loaded in the new AppDomain - } - } - } - - private static ModuleInfo CreateModuleInfo(Type type) - { - string moduleName = type.Name; - List dependsOn = new List(); - bool onDemand = false; - var moduleAttribute = - CustomAttributeData.GetCustomAttributes(type).FirstOrDefault( - cad => cad.Constructor.DeclaringType.FullName == typeof(ModuleAttribute).FullName); - - if (moduleAttribute != null) - { - foreach (CustomAttributeNamedArgument argument in moduleAttribute.NamedArguments) - { - string argumentName = argument.MemberInfo.Name; - switch (argumentName) - { - case "ModuleName": - moduleName = (string)argument.TypedValue.Value; - break; - - case "OnDemand": - onDemand = (bool)argument.TypedValue.Value; - break; - - case "StartupLoaded": - onDemand = !((bool)argument.TypedValue.Value); - break; - } - } - } - - var moduleDependencyAttributes = - CustomAttributeData.GetCustomAttributes(type).Where( - cad => cad.Constructor.DeclaringType.FullName == typeof(ModuleDependencyAttribute).FullName); - - foreach (CustomAttributeData cad in moduleDependencyAttributes) - { - dependsOn.Add((string)cad.ConstructorArguments[0].Value); - } - - ModuleInfo moduleInfo = new ModuleInfo(moduleName, type.AssemblyQualifiedName) - { - InitializationMode = - onDemand - ? InitializationMode.OnDemand - : InitializationMode.WhenAvailable, - Ref = type.Assembly.EscapedCodeBase, - }; - moduleInfo.DependsOn.AddRange(dependsOn); - return moduleInfo; - } - } - } -} diff --git a/src/Prism.Avalonia/Prism.Avalonia.csproj b/src/Prism.Avalonia/Prism.Avalonia.csproj index 1982743..9f94482 100644 --- a/src/Prism.Avalonia/Prism.Avalonia.csproj +++ b/src/Prism.Avalonia/Prism.Avalonia.csproj @@ -8,7 +8,8 @@ Properties Prism - netcoreapp3.1;net6.0;net7.0;net8.0 + net8.0;net9.0;net10.0 + false Prism.Avalonia is a fully open source version of the Prism guidance originally produced by Microsoft Patterns & Practices. Prism.Avalonia provides an implementation of a collection of design patterns that are helpful in writing well structured, maintainable, and testable XAML applications, including MVVM, dependency injection, commanding, event aggregation, and more. Prism's core functionality is a shared library targeting the .NET Framework and .NET Standard. Features that need to be platform specific are implemented in the respective libraries for the target platform (Avalonia, WPF, Uno Platform, and Xamarin Forms). Prism.Avalonia helps you more easily design and build rich, flexible, and easy to maintain cross-platform Avalonia desktop applications. This library provides user interface composition as well as modularity support. @@ -20,18 +21,6 @@ Prism.Avalonia helps you more easily design and build rich, flexible, and easy t Prism.Avalonia.png - - - - - - - - - - - - True diff --git a/src/Prism.DryIoc.Avalonia/Prism.DryIoc.Avalonia.csproj b/src/Prism.DryIoc.Avalonia/Prism.DryIoc.Avalonia.csproj index ad0188f..4ff63b4 100644 --- a/src/Prism.DryIoc.Avalonia/Prism.DryIoc.Avalonia.csproj +++ b/src/Prism.DryIoc.Avalonia/Prism.DryIoc.Avalonia.csproj @@ -7,7 +7,7 @@ Prism.DryIoc - netcoreapp3.1;net6.0;net7.0;net8.0 + net8.0;net9.0;net10.0 This extension is used to build Prism.Avalonia applications based on DryIoc. Users must install the Prism.Avalonia NuGet package as well. Damian Suess, various contributors Copyright (c) 2024 Xeno Innovations, Inc. diff --git a/tests/Avalonia/Prism.Avalonia.Tests/Prism.Avalonia.Tests.csproj b/tests/Avalonia/Prism.Avalonia.Tests/Prism.Avalonia.Tests.csproj index bb58862..3271f3b 100644 --- a/tests/Avalonia/Prism.Avalonia.Tests/Prism.Avalonia.Tests.csproj +++ b/tests/Avalonia/Prism.Avalonia.Tests/Prism.Avalonia.Tests.csproj @@ -1,10 +1,11 @@  - net8.0 + net10.0 enable enable false + false @@ -12,11 +13,11 @@ - + - - + + runtime; build; native; contentfiles; analyzers; buildtransitive all @@ -24,7 +25,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - +