├── samples ├── ViewDiscovery │ ├── Views │ │ ├── ViewA.xaml │ │ ├── MainWindow.xaml │ │ ├── ViewA.xaml.cs │ │ └── MainWindow.xaml.cs │ ├── App.xaml │ ├── Bootstrapper.cs │ ├── ViewDiscovery.csproj │ └── App.xaml.cs ├── ModulesSample.Infrastructure │ ├── Events │ │ └── DummyEvent.cs │ ├── Modularity │ │ ├── ModuleInitializationStatus.cs │ │ ├── KnownModuleNames.cs │ │ └── IModuleTracker.cs │ └── ModulesSample.Infrastructure.csproj ├── DummyModule │ ├── View │ │ ├── DummyModuleView.xaml │ │ └── DummyModuleView.xaml.cs │ ├── DummyModule.csproj │ └── DummyModule.cs ├── ModulesSample │ ├── App.xaml │ ├── MainWindow.xaml │ ├── Module System Logic │ │ ├── DiscoveryMethod.cs │ │ ├── ModuleTracker.cs │ │ └── ModuleTrackingState.cs │ ├── ModulesSample.csproj │ ├── App.xaml.cs │ ├── MainWindow.xaml.cs │ └── CallbackLogger.cs ├── BootstrapperShellSample │ ├── App.xaml │ ├── Views │ │ ├── MainWindow.xaml │ │ └── MainWindow.xaml.cs │ ├── Bootstrapper.cs │ ├── BootstrapperShellSample.csproj │ └── App.xaml.cs └── DummyModule2 │ ├── View │ ├── DummyModuleView2.xaml │ └── DummyModuleView2.xaml.cs │ ├── DummyModule2.csproj │ └── DumyModule2.cs ├── tests ├── Prism.Avalonia.Tests │ ├── Mocks │ │ ├── Views │ │ │ ├── Mock.cs │ │ │ └── MockView.cs │ │ ├── MockDependencyObject.cs │ │ ├── MockClickableObject.cs │ │ ├── MockSortableViews.cs │ │ ├── MockRegionBehaviorCollection.cs │ │ ├── MockFrameworkElement.cs │ │ ├── MockLogger.cs │ │ ├── MockDelegateReference.cs │ │ ├── MockHostAwareRegionBehavior.cs │ │ ├── MockRegionBehavior.cs │ │ ├── MockConfigurationStore.Desktop.cs │ │ ├── ViewModels │ │ │ └── MockViewModel.cs │ │ ├── MockRegionAdapter.cs │ │ ├── MockCommand.cs │ │ ├── MockContainerAdapter.cs │ │ ├── MockViewsCollection.cs │ │ ├── MockRegionManagerAccessor.cs │ │ ├── MockServiceLocator.cs │ │ ├── MockModuleTypeLoader.cs │ │ └── MockAsyncModuleTypeLoader.cs │ ├── Modularity │ │ ├── ModuleInfoGroupFixture.cs │ │ ├── ModuleAttributeFixture.Desktop.cs │ │ └── ModuleCatalogXaml │ │ │ └── SimpleModuleCatalog.xaml │ ├── Regions │ │ ├── SingleActiveRegionFixture.cs │ │ ├── AllActiveRegionFixture.cs │ │ ├── RegionBehaviorCollectionFixture.cs │ │ ├── RegionBehaviorFixture.cs │ │ ├── NavigationContextFixture.cs │ │ └── RegionBehaviorFactoryFixture.cs │ ├── ExceptionAssert.cs │ ├── CollectionChangedTracker.cs │ ├── Prism.Avalonia.Tests.csproj │ └── Logging │ │ └── TextLoggerFixture.cs ├── Prism.IocContainer.Avalonia.Tests.Support │ ├── Mocks │ │ ├── MockService.cs │ │ ├── Views │ │ │ └── MockView.cs │ │ ├── MockModuleLoader.cs │ │ ├── DependantB.cs │ │ ├── DependantA.cs │ │ ├── MockLoggerAdapter.cs │ │ └── ViewModels │ │ │ └── MockViewModel.cs │ ├── Prism.IocContainer.Avalonia.Tests.Support.csproj │ └── BootstrapperFixtureBase.cs ├── Prism.DryIoc.Avalonia.Tests │ ├── Prism.DryIoc.Avalonia.Tests.csproj │ ├── DryIocBootstrapperNullLoggerFixture.cs │ ├── DryIocBootstrapperNullContainerFixture.cs │ ├── DryIocBootstrapperNullModuleCatalogFixture.cs │ ├── DryIocBootstrapperRegisterForNavigationFixture.cs │ └── DryIocBootstrapperNullModuleManagerFixture.cs └── Prism.Autofac.Avalonia.Tests │ ├── Prism.Autofac.Avalonia.Tests.csproj │ ├── Mocks │ └── MockServiceLocator.cs │ ├── AutofacBootstrapperNullLoggerFixture.cs │ ├── AutofacBootstrapperNullModuleCatalogFixture.cs │ ├── AutofacBootstrapperNullModuleManagerFixture.cs │ └── AutofacBootstrapperNullContainerFixture.cs ├── src ├── Prism.Avalonia │ ├── Modularity │ │ ├── ModuleInfo.Desktop.cs │ │ ├── IModule.cs │ │ ├── IModuleInitializer.cs │ │ ├── IConfigurationStore.Desktop.cs │ │ ├── IAssemblyResolver.Desktop.cs │ │ ├── IModuleCatalogItem.cs │ │ ├── InitializationMode.cs │ │ ├── ConfigurationStore.Desktop.cs │ │ ├── DuplicateModuleException.Desktop.cs │ │ ├── CyclicDependencyFoundException.Desktop.cs │ │ ├── ModuleInitializeException.Desktop.cs │ │ ├── ModuleTypeLoadingException.Desktop.cs │ │ ├── ModuleTypeLoaderNotFoundException.Desktop.cs │ │ ├── ModuleNotFoundException.Desktop.cs │ │ ├── ModulesConfigurationSection.Desktop.cs │ │ ├── ModuleAttribute.Desktop.cs │ │ ├── ModuleDependencyAttribute.Desktop.cs │ │ ├── ModuleManager.Desktop.cs │ │ ├── IModuleManager.cs │ │ ├── ModuleState.cs │ │ ├── ModuleDependencyConfigurationElement.Desktop.cs │ │ ├── IModuleTypeLoader.cs │ │ ├── ModularityException.Desktop.cs │ │ ├── LoadModuleCompletedEventArgs.cs │ │ ├── CyclicDependencyFoundException.cs │ │ ├── ModuleDownloadProgressChangedEventArgs.cs │ │ ├── IModuleCatalog.cs │ │ ├── ModuleTypeLoaderNotFoundException.cs │ │ └── DuplicateModuleException.cs │ ├── Regions │ │ ├── SyncActiveStateAttribute.cs │ │ ├── IRegionBehavior.cs │ │ ├── IJournalAware.cs │ │ ├── IRegionNavigationJournalEntry.cs │ │ ├── IRegionMemberLifetime.cs │ │ ├── IRegionAdapter.cs │ │ ├── IViewsCollection.cs │ │ ├── Behaviors │ │ │ ├── IHostAwareRegionBehavior.cs │ │ │ ├── RegionCreationException.Desktop.cs │ │ │ └── RegionCreationException.cs │ │ ├── UpdateRegionsException.Desktop.cs │ │ ├── ViewSortHintAttribute.cs │ │ ├── SingleActiveRegion.cs │ │ ├── IConfirmNavigationRequest.cs │ │ ├── ViewRegistrationException.Desktop.cs │ │ ├── RegionMemberLifetimeAttribute.cs │ │ ├── IRegionNavigationContentLoader.cs │ │ ├── ViewRegisteredEventArgs.cs │ │ ├── IRegionNavigationService.cs │ │ ├── AllActiveRegion.cs │ │ ├── INavigationAware.cs │ │ ├── RegionNavigationJournalEntry.cs │ │ ├── IRegionBehaviorCollection.cs │ │ ├── IRegionManagerAccessor.cs │ │ ├── RegionNavigationEventArgs.cs │ │ ├── UpdateRegionsException.cs │ │ ├── ViewRegistrationException.cs │ │ ├── NavigationResult.cs │ │ ├── RegionBehavior.cs │ │ ├── INavigateAsync.cs │ │ ├── IRegionBehaviorFactory.cs │ │ ├── DefaultRegionManagerAccessor.cs │ │ ├── IRegionViewRegistry.cs │ │ ├── RegionContext.cs │ │ ├── RegionNavigationFailedEventArgs.cs │ │ ├── IRegionNavigationJournal.cs │ │ └── IRegionCollection.cs │ ├── Logging │ │ └── TraceLogger.cs │ ├── Events │ │ └── WeakDelegatesManager.cs │ ├── Common │ │ ├── MvvmHelpers.cs │ │ ├── UriParsingHelper.cs │ │ └── ObservableObject.cs │ ├── Extensions │ │ ├── CollectionExtensions.cs │ │ └── ServiceLocatorExtensions.cs │ ├── Prism.Avalonia.csproj │ └── Mvvm │ │ └── ViewModelLocator.cs ├── Prism.Autofac.Avalonia │ ├── GlobalSuppressions.cs │ ├── Prism.Autofac.Avalonia.csproj │ ├── AutofacServiceLocatorAdapter.cs │ ├── AutofacExtensions.cs │ └── Regions │ │ └── AutofacRegionNavigationContentLoader.cs └── Prism.DryIoc.Avalonia │ ├── GlobalSuppressions.cs │ ├── Prism.DryIoc.Avalonia.csproj │ ├── DryIocServiceLocatorAdapter.cs │ └── DryIocExtensions.cs ├── LICENSE └── README.md /samples/ViewDiscovery/Views/ViewA.xaml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /tests/Prism.Avalonia.Tests/Mocks/Views/Mock.cs: -------------------------------------------------------------------------------- 1 | using Avalonia.Controls; 2 | 3 | namespace Prism.Avalonia.Tests.Mocks.Views 4 | { 5 | public class Mock : Control 6 | { 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /tests/Prism.Avalonia.Tests/Mocks/Views/MockView.cs: -------------------------------------------------------------------------------- 1 | using Avalonia.Controls; 2 | 3 | namespace Prism.Avalonia.Tests.Mocks.Views 4 | { 5 | public class MockView : Control 6 | { 7 | } 8 | } -------------------------------------------------------------------------------- /samples/ModulesSample.Infrastructure/Events/DummyEvent.cs: -------------------------------------------------------------------------------- 1 | using Prism.Events; 2 | 3 | namespace Prism.Avalonia.Infrastructure.Events 4 | { 5 | public class DummyEvent : PubSubEvent 6 | { 7 | 8 | } 9 | } -------------------------------------------------------------------------------- /src/Prism.Avalonia/Modularity/ModuleInfo.Desktop.cs: -------------------------------------------------------------------------------- 1 | 2 | 3 | using System; 4 | 5 | namespace Prism.Modularity 6 | { 7 | [Serializable] 8 | public partial class ModuleInfo 9 | { 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tests/Prism.Avalonia.Tests/Mocks/MockDependencyObject.cs: -------------------------------------------------------------------------------- 1 | 2 | 3 | using Avalonia; 4 | 5 | namespace Prism.Avalonia.Tests.Mocks 6 | { 7 | public class MockDependencyObject : Visual 8 | { 9 | } 10 | } -------------------------------------------------------------------------------- /tests/Prism.IocContainer.Avalonia.Tests.Support/Mocks/MockService.cs: -------------------------------------------------------------------------------- 1 | namespace Prism.IocContainer.Avalonia.Tests.Support.Mocks 2 | { 3 | public class MockService : IService 4 | { 5 | } 6 | 7 | public interface IService { } 8 | } -------------------------------------------------------------------------------- /tests/Prism.IocContainer.Avalonia.Tests.Support/Mocks/Views/MockView.cs: -------------------------------------------------------------------------------- 1 | using Avalonia.Controls; 2 | 3 | namespace Prism.IocContainer.Avalonia.Tests.Support.Mocks.Views 4 | { 5 | public class MockView : Control 6 | { 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /samples/ModulesSample.Infrastructure/Modularity/ModuleInitializationStatus.cs: -------------------------------------------------------------------------------- 1 | namespace Prism.Avalonia.Infrastructure 2 | { 3 | public enum ModuleInitializationStatus 4 | { 5 | NotStarted, 6 | Constructed, 7 | Initialized 8 | } 9 | } -------------------------------------------------------------------------------- /samples/ViewDiscovery/Views/MainWindow.xaml: -------------------------------------------------------------------------------- 1 | 4 | 5 | -------------------------------------------------------------------------------- /tests/Prism.Avalonia.Tests/Mocks/MockClickableObject.cs: -------------------------------------------------------------------------------- 1 | using Avalonia.Controls; 2 | 3 | namespace Prism.Avalonia.Tests.Mocks 4 | { 5 | internal class MockClickableObject : Button 6 | { 7 | public void RaiseClick() 8 | { 9 | OnClick(); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /samples/ModulesSample.Infrastructure/ModulesSample.Infrastructure.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /samples/DummyModule/View/DummyModuleView.xaml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /samples/ModulesSample/App.xaml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /samples/ViewDiscovery/App.xaml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /samples/BootstrapperShellSample/App.xaml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /samples/DummyModule2/View/DummyModuleView2.xaml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/Prism.Avalonia/Modularity/IModule.cs: -------------------------------------------------------------------------------- 1 | namespace Prism.Modularity 2 | { 3 | /// 4 | /// Defines the contract for the modules deployed in the application. 5 | /// 6 | public interface IModule 7 | { 8 | /// 9 | /// Notifies the module that it has be initialized. 10 | /// 11 | void Initialize(); 12 | } 13 | } -------------------------------------------------------------------------------- /tests/Prism.IocContainer.Avalonia.Tests.Support/Mocks/MockModuleLoader.cs: -------------------------------------------------------------------------------- 1 | using Prism.Modularity; 2 | 3 | namespace Prism.IocContainer.Avalonia.Tests.Support.Mocks 4 | { 5 | public class MockModuleInitializer : IModuleInitializer 6 | { 7 | public bool LoadCalled; 8 | 9 | public void Initialize(ModuleInfo moduleInfo) 10 | { 11 | LoadCalled = true; 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /samples/ModulesSample.Infrastructure/Modularity/KnownModuleNames.cs: -------------------------------------------------------------------------------- 1 | namespace Prism.Avalonia.Infrastructure 2 | { 3 | /// 4 | /// A set of known module names for communication with IModuleTracker 5 | /// 6 | public static class KnownModuleNames 7 | { 8 | public const string ModuleDummy = "DummyModule"; 9 | 10 | public const string ModuleDummy2 = "DummyModule2"; 11 | } 12 | } -------------------------------------------------------------------------------- /tests/Prism.Avalonia.Tests/Mocks/MockSortableViews.cs: -------------------------------------------------------------------------------- 1 | 2 | 3 | using Prism.Regions; 4 | 5 | namespace Prism.Avalonia.Tests.Mocks 6 | { 7 | [ViewSortHint("01")] 8 | internal class MockSortableView1 9 | { 10 | } 11 | 12 | [ViewSortHint("02")] 13 | internal class MockSortableView2 14 | { 15 | } 16 | 17 | [ViewSortHint("03")] 18 | internal class MockSortableView3 19 | { 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /samples/BootstrapperShellSample/Views/MainWindow.xaml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /tests/Prism.Avalonia.Tests/Mocks/MockRegionBehaviorCollection.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using Prism.Regions; 4 | 5 | namespace Prism.Avalonia.Tests.Mocks 6 | { 7 | internal class MockRegionBehaviorCollection : Dictionary, IRegionBehaviorCollection 8 | { 9 | IEnumerator IEnumerable.GetEnumerator() 10 | { 11 | return GetEnumerator(); 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /tests/Prism.Avalonia.Tests/Mocks/MockFrameworkElement.cs: -------------------------------------------------------------------------------- 1 | using Avalonia; 2 | using Avalonia.Controls; 3 | using Avalonia.Interactivity; 4 | 5 | namespace Prism.Avalonia.Tests.Mocks 6 | { 7 | public class MockFrameworkElement : Control 8 | { 9 | public void RaiseLoaded() 10 | { 11 | RaiseLoaded(); 12 | } 13 | 14 | public void RaiseUnloaded() 15 | { 16 | RaiseUnloaded(); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/Prism.IocContainer.Avalonia.Tests.Support/Mocks/DependantB.cs: -------------------------------------------------------------------------------- 1 | namespace Prism.IocContainer.Avalonia.Tests.Support.Mocks 2 | { 3 | public class DependantB : IDependantB 4 | { 5 | public DependantB(IService service) 6 | { 7 | MyService = service; 8 | } 9 | 10 | public IService MyService { get; set; } 11 | } 12 | 13 | public interface IDependantB 14 | { 15 | IService MyService { get; } 16 | } 17 | } -------------------------------------------------------------------------------- /tests/Prism.Avalonia.Tests/Mocks/MockLogger.cs: -------------------------------------------------------------------------------- 1 | using Prism.Logging; 2 | 3 | namespace Prism.Avalonia.Tests.Mocks 4 | { 5 | internal class MockLogger : ILoggerFacade 6 | { 7 | public string LastMessage; 8 | public Category LastMessageCategory; 9 | public void Log(string message, Category category, Priority priority) 10 | { 11 | LastMessage = message; 12 | LastMessageCategory = category; 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /tests/Prism.Avalonia.Tests/Mocks/MockDelegateReference.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Prism.Events; 3 | 4 | namespace Prism.Avalonia.Tests.Mocks 5 | { 6 | class MockDelegateReference : IDelegateReference 7 | { 8 | public Delegate Target { get; set; } 9 | 10 | public MockDelegateReference() 11 | { 12 | 13 | } 14 | 15 | public MockDelegateReference(Delegate target) 16 | { 17 | Target = target; 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /tests/Prism.Avalonia.Tests/Mocks/MockHostAwareRegionBehavior.cs: -------------------------------------------------------------------------------- 1 | using Avalonia; 2 | using Prism.Regions; 3 | using Prism.Regions.Behaviors; 4 | 5 | namespace Prism.Avalonia.Tests.Mocks 6 | { 7 | public class MockHostAwareRegionBehavior : IHostAwareRegionBehavior 8 | { 9 | public IRegion Region { get; set; } 10 | 11 | public void Attach() 12 | { 13 | 14 | } 15 | 16 | public Visual HostControl { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Prism.Avalonia/Regions/SyncActiveStateAttribute.cs: -------------------------------------------------------------------------------- 1 | 2 | 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | 8 | namespace Prism.Regions 9 | { 10 | /// 11 | /// Defines that a view is synchronized with its parent view's Active state. 12 | /// 13 | [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] 14 | public sealed class SyncActiveStateAttribute : Attribute 15 | { 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tests/Prism.IocContainer.Avalonia.Tests.Support/Mocks/DependantA.cs: -------------------------------------------------------------------------------- 1 | namespace Prism.IocContainer.Avalonia.Tests.Support.Mocks 2 | { 3 | public class DependantA : IDependantA 4 | { 5 | public DependantA(IDependantB dependantB) 6 | { 7 | MyDependantB = dependantB; 8 | } 9 | 10 | public IDependantB MyDependantB { get; set; } 11 | } 12 | 13 | public interface IDependantA 14 | { 15 | IDependantB MyDependantB { get; } 16 | } 17 | } -------------------------------------------------------------------------------- /tests/Prism.IocContainer.Avalonia.Tests.Support/Mocks/MockLoggerAdapter.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Prism.Logging; 3 | 4 | namespace Prism.IocContainer.Avalonia.Tests.Support.Mocks 5 | { 6 | public class MockLoggerAdapter : ILoggerFacade 7 | { 8 | public IList Messages = new List(); 9 | 10 | public void Log(string message, Category category, Priority priority) 11 | { 12 | Messages.Add(message); 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /src/Prism.Avalonia/Modularity/IModuleInitializer.cs: -------------------------------------------------------------------------------- 1 | namespace Prism.Modularity 2 | { 3 | /// 4 | /// Declares a service which initializes the modules into the application. 5 | /// 6 | public interface IModuleInitializer 7 | { 8 | /// 9 | /// Initializes the specified module. 10 | /// 11 | /// The module to initialize 12 | void Initialize(ModuleInfo moduleInfo); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Prism.Avalonia/Modularity/IConfigurationStore.Desktop.cs: -------------------------------------------------------------------------------- 1 | namespace Prism.Modularity 2 | { 3 | /// 4 | /// Defines a store for the module metadata. 5 | /// 6 | public interface IConfigurationStore 7 | { 8 | /// 9 | /// Gets the module configuration data. 10 | /// 11 | /// A instance. 12 | ModulesConfigurationSection RetrieveModuleConfigurationSection(); 13 | } 14 | } -------------------------------------------------------------------------------- /tests/Prism.Avalonia.Tests/Mocks/MockRegionBehavior.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Prism.Regions; 3 | 4 | namespace Prism.Avalonia.Tests.Mocks 5 | { 6 | public class MockRegionBehavior : IRegionBehavior 7 | { 8 | public IRegion Region 9 | { 10 | get; set; 11 | } 12 | 13 | public Func OnAttach; 14 | 15 | public void Attach() 16 | { 17 | if (OnAttach != null) 18 | OnAttach(); 19 | 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Prism.Avalonia/Modularity/IAssemblyResolver.Desktop.cs: -------------------------------------------------------------------------------- 1 | namespace Prism.Modularity 2 | { 3 | /// 4 | /// Interface for classes that are responsible for resolving and loading assembly files. 5 | /// 6 | public interface IAssemblyResolver 7 | { 8 | /// 9 | /// Load an assembly when it's required by the application. 10 | /// 11 | /// 12 | void LoadAssemblyFrom(string assemblyFilePath); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Prism.Avalonia/Modularity/IModuleCatalogItem.cs: -------------------------------------------------------------------------------- 1 | namespace Prism.Modularity 2 | { 3 | /// 4 | /// Marker interface that allows both s and s to be 5 | /// added to the from code and XAML. 6 | /// 7 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1040:AvoidEmptyInterfaces", Justification = "This is a marker interface")] 8 | public interface IModuleCatalogItem 9 | { 10 | 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /samples/ViewDiscovery/Views/ViewA.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Avalonia.Controls; 3 | using Avalonia.Markup.Xaml; 4 | 5 | namespace ViewDiscovery.Views 6 | { 7 | /// 8 | /// Interaction logic for ViewA.xaml 9 | /// 10 | public partial class ViewA : UserControl 11 | { 12 | public ViewA() 13 | { 14 | this.InitializeComponent(); 15 | } 16 | 17 | private void InitializeComponent() 18 | { 19 | AvaloniaXamlLoader.Load(this); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Prism.Avalonia/Regions/IRegionBehavior.cs: -------------------------------------------------------------------------------- 1 | namespace Prism.Regions 2 | { 3 | /// 4 | /// Interface for allowing extensible behavior on regions. 5 | /// 6 | public interface IRegionBehavior 7 | { 8 | /// 9 | /// The region that this behavior is extending. 10 | /// 11 | IRegion Region { get; set; } 12 | 13 | /// 14 | /// Attaches the behavior to the specified region. 15 | /// 16 | void Attach(); 17 | 18 | } 19 | } -------------------------------------------------------------------------------- /src/Prism.Avalonia/Regions/IJournalAware.cs: -------------------------------------------------------------------------------- 1 | namespace Prism.Regions 2 | { 3 | /// 4 | /// Provides a way for objects involved in navigation to opt-out of being added to the IRegionNavigationJournal backstack. 5 | /// 6 | public interface IJournalAware 7 | { 8 | /// 9 | /// Determines if the current obect is going to be added to the navigation journal's backstack. 10 | /// 11 | /// True, add to backstack. False, remove from backstack. 12 | bool PersistInHistory(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /samples/DummyModule/View/DummyModuleView.xaml.cs: -------------------------------------------------------------------------------- 1 | using Avalonia.Controls; 2 | using Avalonia.Markup.Xaml; 3 | using Prism.Events; 4 | 5 | namespace DummyModule.View 6 | { 7 | public class DummyModuleView : UserControl 8 | { 9 | private readonly IEventAggregator eventAggregator; 10 | 11 | private TextBox logTextBox; 12 | 13 | public DummyModuleView() 14 | { 15 | this.InitializeComponent(); 16 | } 17 | 18 | private void InitializeComponent() 19 | { 20 | AvaloniaXamlLoader.Load(this); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /tests/Prism.IocContainer.Avalonia.Tests.Support/Mocks/ViewModels/MockViewModel.cs: -------------------------------------------------------------------------------- 1 | using Prism.Mvvm; 2 | 3 | namespace Prism.IocContainer.Avalonia.Tests.Support.Mocks.ViewModels 4 | { 5 | public class MockViewModel : BindableBase 6 | { 7 | private IService _mockService; 8 | public IService MockService 9 | { 10 | get { return _mockService; } 11 | set { SetProperty(ref _mockService, value); } 12 | } 13 | 14 | public MockViewModel(IService mockService) 15 | { 16 | _mockService = mockService; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /samples/BootstrapperShellSample/Views/MainWindow.xaml.cs: -------------------------------------------------------------------------------- 1 | using Avalonia; 2 | using Avalonia.Controls; 3 | using Avalonia.Markup.Xaml; 4 | 5 | namespace BootstrapperShellSample.Views 6 | { 7 | /// 8 | /// Interaction logic for MainWindow.xaml 9 | /// 10 | public partial class MainWindow : Window 11 | { 12 | public MainWindow() 13 | { 14 | this.InitializeComponent(); 15 | this.AttachDevTools(); 16 | } 17 | 18 | private void InitializeComponent() 19 | { 20 | AvaloniaXamlLoader.Load(this); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Prism.Avalonia/Modularity/InitializationMode.cs: -------------------------------------------------------------------------------- 1 | namespace Prism.Modularity 2 | { 3 | /// 4 | /// Specifies on which stage the Module group will be initialized. 5 | /// 6 | public enum InitializationMode 7 | { 8 | /// 9 | /// The module will be initialized when it is available on application start-up. 10 | /// 11 | WhenAvailable, 12 | 13 | /// 14 | /// The module will be initialized when requested, and not automatically on application start-up. 15 | /// 16 | OnDemand 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /samples/ViewDiscovery/Views/MainWindow.xaml.cs: -------------------------------------------------------------------------------- 1 | using Avalonia; 2 | using Avalonia.Controls; 3 | using Avalonia.Markup.Xaml; 4 | using Prism.Regions; 5 | 6 | namespace ViewDiscovery.Views 7 | { 8 | public class MainWindow : Window 9 | { 10 | public MainWindow(IRegionManager regionManager) 11 | { 12 | this.InitializeComponent(); 13 | this.AttachDevTools(); 14 | 15 | regionManager.RegisterViewWithRegion("ContentRegion", typeof(ViewA)); 16 | } 17 | 18 | private void InitializeComponent() 19 | { 20 | AvaloniaXamlLoader.Load(this); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Prism.Avalonia/Regions/IRegionNavigationJournalEntry.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace Prism.Regions 3 | { 4 | /// 5 | /// An entry in an IRegionNavigationJournal representing the URI navigated to. 6 | /// 7 | public interface IRegionNavigationJournalEntry 8 | { 9 | /// 10 | /// Gets or sets the URI. 11 | /// 12 | /// The URI. 13 | Uri Uri { get; set; } 14 | 15 | /// 16 | /// Gets or sets the NavigationParameters instance. 17 | /// 18 | NavigationParameters Parameters { get; set; } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /tests/Prism.Avalonia.Tests/Mocks/MockConfigurationStore.Desktop.cs: -------------------------------------------------------------------------------- 1 | 2 | 3 | using Prism.Modularity; 4 | 5 | namespace Prism.Avalonia.Tests.Mocks 6 | { 7 | public class MockConfigurationStore : IConfigurationStore 8 | { 9 | private ModulesConfigurationSection _section = new ModulesConfigurationSection(); 10 | 11 | public ModuleConfigurationElement[] Modules 12 | { 13 | set { _section.Modules = new ModuleConfigurationElementCollection(value); } 14 | } 15 | 16 | public ModulesConfigurationSection RetrieveModuleConfigurationSection() 17 | { 18 | return _section; 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /src/Prism.Avalonia/Regions/IRegionMemberLifetime.cs: -------------------------------------------------------------------------------- 1 | 2 | 3 | using Prism.Regions.Behaviors; 4 | 5 | namespace Prism.Regions 6 | { 7 | /// 8 | /// When implemented, allows an instance placed in a 9 | /// that uses a to indicate 10 | /// it should be removed when it transitions from an activated to deactived state. 11 | /// 12 | public interface IRegionMemberLifetime 13 | { 14 | /// 15 | /// Gets a value indicating whether this instance should be kept-alive upon deactivation. 16 | /// 17 | bool KeepAlive { get; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Prism.Autofac.Avalonia/GlobalSuppressions.cs: -------------------------------------------------------------------------------- 1 | 2 | 3 | // This file is used by Code Analysis to maintain SuppressMessage 4 | // attributes that are applied to this project. 5 | // Project-level suppressions either have no target or are given 6 | // a specific target and scoped to a namespace, type, member, etc. 7 | // 8 | // To add a suppression to this file, right-click the message in the 9 | // Error List, point to "Suppress Message(s)", and click 10 | // "In Project Suppression File". 11 | // You do not need to add suppressions to this file manually. 12 | 13 | [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA2210:AssembliesShouldHaveValidStrongNames")] 14 | -------------------------------------------------------------------------------- /src/Prism.DryIoc.Avalonia/GlobalSuppressions.cs: -------------------------------------------------------------------------------- 1 | 2 | 3 | // This file is used by Code Analysis to maintain SuppressMessage 4 | // attributes that are applied to this project. 5 | // Project-level suppressions either have no target or are given 6 | // a specific target and scoped to a namespace, type, member, etc. 7 | // 8 | // To add a suppression to this file, right-click the message in the 9 | // Error List, point to "Suppress Message(s)", and click 10 | // "In Project Suppression File". 11 | // You do not need to add suppressions to this file manually. 12 | 13 | [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA2210:AssembliesShouldHaveValidStrongNames")] 14 | -------------------------------------------------------------------------------- /samples/DummyModule/DummyModule.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | 6 | 7 | 8 | 9 | Designer 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | DummyModuleView.xaml 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /tests/Prism.IocContainer.Avalonia.Tests.Support/Prism.IocContainer.Avalonia.Tests.Support.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.0 5 | 6 | false 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /samples/DummyModule2/DummyModule2.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | 6 | 7 | 8 | 9 | Designer 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | DummyModuleView2.xaml 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /tests/Prism.Avalonia.Tests/Mocks/ViewModels/MockViewModel.cs: -------------------------------------------------------------------------------- 1 | using Prism.Mvvm; 2 | 3 | namespace Prism.Avalonia.Tests.Mocks.ViewModels 4 | { 5 | public class MockViewModel : BindableBase 6 | { 7 | private int mockProperty; 8 | 9 | public int MockProperty 10 | { 11 | get 12 | { 13 | return this.mockProperty; 14 | } 15 | 16 | set 17 | { 18 | this.SetProperty(ref mockProperty, value); 19 | } 20 | } 21 | 22 | internal void InvokeOnPropertyChanged() 23 | { 24 | this.RaisePropertyChanged(nameof(MockProperty)); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Prism.Avalonia/Modularity/ConfigurationStore.Desktop.cs: -------------------------------------------------------------------------------- 1 | using System.Configuration; 2 | 3 | namespace Prism.Modularity 4 | { 5 | /// 6 | /// Defines a store for the module metadata. 7 | /// 8 | public class ConfigurationStore : IConfigurationStore 9 | { 10 | /// 11 | /// Gets the module configuration data. 12 | /// 13 | /// A instance. 14 | public ModulesConfigurationSection RetrieveModuleConfigurationSection() 15 | { 16 | return ConfigurationManager.GetSection("modules") as ModulesConfigurationSection; 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /tests/Prism.Avalonia.Tests/Modularity/ModuleInfoGroupFixture.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.VisualStudio.TestTools.UnitTesting; 2 | using Prism.Modularity; 3 | 4 | namespace Prism.Avalonia.Tests.Modularity 5 | { 6 | [TestClass] 7 | public class ModuleInfoGroupFixture 8 | { 9 | [TestMethod] 10 | public void ShouldForwardValuesToModuleInfo() 11 | { 12 | ModuleInfoGroup group = new ModuleInfoGroup(); 13 | group.Ref = "MyCustomGroupRef"; 14 | ModuleInfo moduleInfo = new ModuleInfo(); 15 | Assert.IsNull(moduleInfo.Ref); 16 | 17 | group.Add(moduleInfo); 18 | 19 | Assert.AreEqual(group.Ref, moduleInfo.Ref); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Prism.Avalonia/Regions/IRegionAdapter.cs: -------------------------------------------------------------------------------- 1 | namespace Prism.Regions 2 | { 3 | /// 4 | /// Defines an interfaces to adapt an object and bind it to a new . 5 | /// 6 | public interface IRegionAdapter 7 | { 8 | /// 9 | /// Adapts an object and binds it to a new . 10 | /// 11 | /// The object to adapt. 12 | /// The name of the region to be created. 13 | /// The new instance of that the is bound to. 14 | IRegion Initialize(object regionTarget, string regionName); 15 | } 16 | } -------------------------------------------------------------------------------- /src/Prism.Avalonia/Regions/IViewsCollection.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Collections.Specialized; 3 | 4 | namespace Prism.Regions 5 | { 6 | /// 7 | /// Defines a view of a collection. 8 | /// 9 | public interface IViewsCollection : IEnumerable, INotifyCollectionChanged 10 | { 11 | /// 12 | /// Determines whether the collection contains a specific value. 13 | /// 14 | /// The object to locate in the collection. 15 | /// if is found in the collection; otherwise, . 16 | bool Contains(object value); 17 | } 18 | } -------------------------------------------------------------------------------- /samples/ViewDiscovery/Bootstrapper.cs: -------------------------------------------------------------------------------- 1 | using ViewDiscovery.Views; 2 | using System.Windows; 3 | using Avalonia; 4 | using Avalonia.Controls; 5 | using DryIoc; 6 | using Prism.DryIoc; 7 | 8 | namespace ViewDiscovery 9 | { 10 | class Bootstrapper : DryIocBootstrapper 11 | { 12 | private AppBuilder AppBuilderInstance; 13 | 14 | protected override IAvaloniaObject CreateShell() 15 | { 16 | AppBuilderInstance = App.BuildAvaloniaApp(); 17 | 18 | return Container.Resolve(); 19 | } 20 | 21 | protected override void InitializeShell() 22 | { 23 | var mainWindow = base.Shell as Window; 24 | mainWindow.Show(); 25 | Application.Current.Run(mainWindow); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /samples/ModulesSample/MainWindow.xaml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/Prism.Avalonia/Modularity/DuplicateModuleException.Desktop.cs: -------------------------------------------------------------------------------- 1 | 2 | 3 | using System; 4 | using System.Runtime.Serialization; 5 | 6 | namespace Prism.Modularity 7 | { 8 | [Serializable] 9 | public partial class DuplicateModuleException 10 | { 11 | /// 12 | /// Initializes a new instance of the class 13 | /// with the serialization data. 14 | /// 15 | /// Holds the serialized object data about the exception being thrown. 16 | /// Contains contextual information about the source or destination. 17 | protected DuplicateModuleException(SerializationInfo info, StreamingContext context) : base(info, context) { } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /samples/BootstrapperShellSample/Bootstrapper.cs: -------------------------------------------------------------------------------- 1 | using System.Threading; 2 | using Avalonia; 3 | using Avalonia.Controls; 4 | using BootstrapperShellSample.Views; 5 | using DryIoc; 6 | using Prism.DryIoc; 7 | 8 | namespace BootstrapperShellSample 9 | { 10 | class Bootstrapper : DryIocBootstrapper 11 | { 12 | private AppBuilder AppBuilderInstance; 13 | 14 | protected override IAvaloniaObject CreateShell() 15 | { 16 | AppBuilderInstance = App.BuildAvaloniaApp(); 17 | 18 | return Container.Resolve(); 19 | } 20 | 21 | protected override void InitializeShell() 22 | { 23 | var mainWindow = base.Shell as MainWindow; 24 | mainWindow.Show(); 25 | Application.Current.Run(mainWindow); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Prism.Avalonia/Modularity/CyclicDependencyFoundException.Desktop.cs: -------------------------------------------------------------------------------- 1 | 2 | 3 | using System; 4 | using System.Runtime.Serialization; 5 | 6 | namespace Prism.Modularity 7 | { 8 | [Serializable] 9 | public partial class CyclicDependencyFoundException 10 | { 11 | /// 12 | /// Initializes a new instance of the class 13 | /// with the serialization data. 14 | /// 15 | /// Holds the serialized object data about the exception being thrown. 16 | /// Contains contextual information about the source or destination. 17 | protected CyclicDependencyFoundException(SerializationInfo info, StreamingContext context) : base(info, context) { } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Prism.Avalonia/Modularity/ModuleInitializeException.Desktop.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Serialization; 3 | 4 | namespace Prism.Modularity 5 | { 6 | [Serializable] 7 | public partial class ModuleInitializeException 8 | { 9 | /// 10 | /// Initializes a new instance with serialized data. 11 | /// 12 | /// The that holds the serialized object data about the exception being thrown. 13 | /// The that contains contextual information about the source or destination. 14 | protected ModuleInitializeException(SerializationInfo info, StreamingContext context) 15 | : base(info, context) 16 | { 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Prism.Avalonia/Modularity/ModuleTypeLoadingException.Desktop.cs: -------------------------------------------------------------------------------- 1 | 2 | 3 | using System; 4 | using System.Runtime.Serialization; 5 | 6 | namespace Prism.Modularity 7 | { 8 | [Serializable] 9 | public partial class ModuleTypeLoadingException 10 | { 11 | /// 12 | /// Initializes a new instance with serialized data. 13 | /// 14 | /// The that holds the serialized object data about the exception being thrown. 15 | /// The that contains contextual information about the source or destination. 16 | protected ModuleTypeLoadingException(SerializationInfo info, StreamingContext context) 17 | : base(info, context) 18 | { 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /samples/DummyModule2/DumyModule2.cs: -------------------------------------------------------------------------------- 1 | using DummyModule2.View; 2 | using Prism.Avalonia.Infrastructure; 3 | using Prism.Modularity; 4 | using Prism.Regions; 5 | 6 | namespace DummyModule2 7 | { 8 | public class DummyModule2 : IModule 9 | { 10 | private readonly IModuleTracker moduleTracker; 11 | private readonly IRegionManager regionManager; 12 | 13 | public DummyModule2(IModuleTracker moduleTracker, IRegionManager regionManager) 14 | { 15 | this.moduleTracker = moduleTracker; 16 | this.regionManager = regionManager; 17 | } 18 | 19 | public void Initialize() 20 | { 21 | this.moduleTracker.RecordModuleInitialized(KnownModuleNames.ModuleDummy); 22 | 23 | regionManager.RegisterViewWithRegion("Region2", typeof(DummyModuleView2)); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Prism.Avalonia/Modularity/ModuleTypeLoaderNotFoundException.Desktop.cs: -------------------------------------------------------------------------------- 1 | 2 | 3 | using System; 4 | using System.Runtime.Serialization; 5 | 6 | namespace Prism.Modularity 7 | { 8 | [Serializable] 9 | public partial class ModuleTypeLoaderNotFoundException 10 | { 11 | /// 12 | /// Initializes a new instance with serialized data. 13 | /// 14 | /// The that holds the serialized object data about the exception being thrown. 15 | /// The that contains contextual information about the source or destination. 16 | protected ModuleTypeLoaderNotFoundException(SerializationInfo info, StreamingContext context) 17 | : base(info, context) 18 | { 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /samples/ModulesSample/Module System Logic/DiscoveryMethod.cs: -------------------------------------------------------------------------------- 1 | namespace ModulesSample.Module_System_Logic 2 | { 3 | /// 4 | /// Describes how a module is discovered 5 | /// 6 | public enum DiscoveryMethod 7 | { 8 | /// 9 | /// The module is directly referenced by the application 10 | /// 11 | ApplicationReference, 12 | 13 | /// 14 | /// The module is listed in a XAML manifest file 15 | /// 16 | XamlManifest, 17 | 18 | /// 19 | /// The module is listed in a configuration file 20 | /// 21 | ConfigurationManifest, 22 | 23 | /// 24 | /// The module is discovered by examining the assemblies in a directory 25 | /// 26 | DirectorySweep 27 | } 28 | } -------------------------------------------------------------------------------- /src/Prism.Avalonia/Regions/Behaviors/IHostAwareRegionBehavior.cs: -------------------------------------------------------------------------------- 1 | using Avalonia; 2 | using Avalonia.Controls; 3 | 4 | namespace Prism.Regions.Behaviors 5 | { 6 | /// 7 | /// Defines a that not allows extensible behaviors on regions which also interact 8 | /// with the target element that the is attached to. 9 | /// 10 | public interface IHostAwareRegionBehavior : IRegionBehavior 11 | { 12 | /// 13 | /// Gets or sets the that the is attached to. 14 | /// 15 | /// A that the is attached to. 16 | /// This is usually a that is part of the tree. 17 | Visual HostControl { get; set; } 18 | } 19 | } -------------------------------------------------------------------------------- /tests/Prism.Avalonia.Tests/Regions/SingleActiveRegionFixture.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.VisualStudio.TestTools.UnitTesting; 2 | using Prism.Regions; 3 | 4 | namespace Prism.Avalonia.Tests.Regions 5 | { 6 | [TestClass] 7 | public class SingleActiveRegionFixture 8 | { 9 | [TestMethod] 10 | public void ActivatingNewViewDeactivatesCurrent() 11 | { 12 | IRegion region = new SingleActiveRegion(); 13 | var view = new object(); 14 | region.Add(view); 15 | region.Activate(view); 16 | 17 | Assert.IsTrue(region.ActiveViews.Contains(view)); 18 | 19 | var view2 = new object(); 20 | region.Add(view2); 21 | region.Activate(view2); 22 | 23 | Assert.IsFalse(region.ActiveViews.Contains(view)); 24 | Assert.IsTrue(region.ActiveViews.Contains(view2)); 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /tests/Prism.DryIoc.Avalonia.Tests/Prism.DryIoc.Avalonia.Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.0 5 | 6 | false 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /tests/Prism.Autofac.Avalonia.Tests/Prism.Autofac.Avalonia.Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.0 5 | 6 | false 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /tests/Prism.Avalonia.Tests/ExceptionAssert.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | 4 | namespace Prism.Avalonia.Tests 5 | { 6 | public static class ExceptionAssert 7 | { 8 | public static void Throws(Action action) 9 | where TException : Exception 10 | { 11 | Throws(typeof(TException), action); 12 | } 13 | 14 | public static void Throws(Type expectedExceptionType, Action action) 15 | { 16 | try 17 | { 18 | action(); 19 | } 20 | catch (Exception ex) 21 | { 22 | Assert.IsInstanceOfType(ex, expectedExceptionType); 23 | return; 24 | } 25 | 26 | Assert.Fail("No exception thrown. Expected exception type of {0}.", expectedExceptionType.Name); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Prism.DryIoc.Avalonia/Prism.DryIoc.Avalonia.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | True 18 | True 19 | Resources.resx 20 | 21 | 22 | 23 | 24 | 25 | PublicResXFileCodeGenerator 26 | Resources.Designer.cs 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/Prism.Autofac.Avalonia/Prism.Autofac.Avalonia.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | True 18 | True 19 | Resources.resx 20 | 21 | 22 | 23 | 24 | 25 | PublicResXFileCodeGenerator 26 | Resources.Designer.cs 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/Prism.Avalonia/Modularity/ModuleNotFoundException.Desktop.cs: -------------------------------------------------------------------------------- 1 | 2 | 3 | using System; 4 | using System.Runtime.Serialization; 5 | 6 | namespace Prism.Modularity 7 | { 8 | /// 9 | /// Exception thrown when a requested is not found. 10 | /// 11 | [Serializable] 12 | public partial class ModuleNotFoundException 13 | { 14 | /// 15 | /// Initializes a new instance of the class 16 | /// with the serialization data. 17 | /// 18 | /// Holds the serialized object data about the exception being thrown. 19 | /// Contains contextual information about the source or destination. 20 | protected ModuleNotFoundException(SerializationInfo info, StreamingContext context) : base(info, context) 21 | { 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /tests/Prism.Avalonia.Tests/Mocks/MockRegionAdapter.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Avalonia; 3 | using Prism.Regions; 4 | 5 | namespace Prism.Avalonia.Tests.Mocks 6 | { 7 | internal class MockRegionAdapter : IRegionAdapter 8 | { 9 | public List CreatedRegions = new List(); 10 | public MockRegionManagerAccessor Accessor; 11 | 12 | 13 | public IRegion Initialize(object regionTarget, string regionName) 14 | { 15 | CreatedRegions.Add(regionName); 16 | 17 | var region = new MockPresentationRegion(); 18 | RegionManager.GetObservableRegion(regionTarget as AvaloniaObject).Value = region; 19 | 20 | // Fire update regions again. This also happens if a region is created and added to the regionmanager 21 | if (this.Accessor != null) 22 | Accessor.UpdateRegions(); 23 | 24 | return region; 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /src/Prism.Avalonia/Regions/Behaviors/RegionCreationException.Desktop.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Serialization; 3 | 4 | namespace Prism.Regions.Behaviors 5 | { 6 | /// 7 | /// 8 | /// 9 | [Serializable] 10 | public partial class RegionCreationException 11 | { 12 | /// 13 | /// Initializes a new instance of the class with serialized data. 14 | /// 15 | /// The that holds the serialized object data about the exception being thrown. 16 | /// The that contains contextual information about the source or destination. 17 | protected RegionCreationException(SerializationInfo info, StreamingContext context) 18 | : base(info, context) 19 | { 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /tests/Prism.Avalonia.Tests/Regions/AllActiveRegionFixture.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | using Prism.Regions; 4 | 5 | namespace Prism.Avalonia.Tests.Regions 6 | { 7 | [TestClass] 8 | public class AllActiveRegionFixture 9 | { 10 | [TestMethod] 11 | public void AddingViewsToRegionMarksThemAsActive() 12 | { 13 | IRegion region = new AllActiveRegion(); 14 | var view = new object(); 15 | 16 | region.Add(view); 17 | 18 | Assert.IsTrue(region.ActiveViews.Contains(view)); 19 | } 20 | 21 | [TestMethod] 22 | [ExpectedException(typeof(InvalidOperationException))] 23 | public void DeactivateThrows() 24 | { 25 | IRegion region = new AllActiveRegion(); 26 | var view = new object(); 27 | region.Add(view); 28 | 29 | region.Deactivate(view); 30 | } 31 | 32 | 33 | } 34 | } -------------------------------------------------------------------------------- /tests/Prism.Avalonia.Tests/CollectionChangedTracker.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Collections.Specialized; 3 | using System.Linq; 4 | 5 | namespace Prism.Avalonia.Tests 6 | { 7 | public class CollectionChangedTracker 8 | { 9 | private readonly List eventList = new List(); 10 | 11 | public CollectionChangedTracker(INotifyCollectionChanged collection) 12 | { 13 | collection.CollectionChanged += OnCollectionChanged; 14 | } 15 | 16 | public IEnumerable ActionsFired { get { return this.eventList.Select(e => e.Action); } } 17 | public IEnumerable NotifyEvents { get { return this.eventList; } } 18 | 19 | private void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) 20 | { 21 | this.eventList.Add(e); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Prism.Avalonia/Regions/UpdateRegionsException.Desktop.cs: -------------------------------------------------------------------------------- 1 | 2 | 3 | using System; 4 | using System.Runtime.Serialization; 5 | 6 | namespace Prism.Regions 7 | { 8 | /// 9 | /// Represents errors that occured during the regions' update. 10 | /// 11 | [Serializable] 12 | public partial class UpdateRegionsException 13 | { 14 | /// 15 | /// Initializes a new instance of the class with serialized data. 16 | /// 17 | /// The that holds the serialized object data about the exception being thrown. 18 | /// The that contains contextual information about the source or destination. 19 | protected UpdateRegionsException(SerializationInfo info, StreamingContext context) 20 | : base(info, context) 21 | { 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Prism.Avalonia/Modularity/ModulesConfigurationSection.Desktop.cs: -------------------------------------------------------------------------------- 1 | using System.Configuration; 2 | 3 | namespace Prism.Modularity 4 | { 5 | /// 6 | /// A for module configuration. 7 | /// 8 | public class ModulesConfigurationSection : ConfigurationSection 9 | { 10 | /// 11 | /// Gets or sets the collection of modules configuration. 12 | /// 13 | /// A of . 14 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] 15 | [ConfigurationProperty("", IsDefaultCollection = true, IsKey = false)] 16 | public ModuleConfigurationElementCollection Modules 17 | { 18 | get { return (ModuleConfigurationElementCollection)base[""]; } 19 | set { base[""] = value; } 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /src/Prism.Avalonia/Regions/ViewSortHintAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net; 3 | using System.Windows; 4 | using System.Windows.Input; 5 | 6 | namespace Prism.Regions 7 | { 8 | /// 9 | /// Provides a hint from a view to a region on how to sort the view. 10 | /// 11 | [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] 12 | public sealed class ViewSortHintAttribute : Attribute 13 | { 14 | /// 15 | /// Initializes a new instance of the class. 16 | /// 17 | /// The hint to use for sorting. 18 | public ViewSortHintAttribute(string hint) 19 | { 20 | this.Hint = hint; 21 | } 22 | 23 | /// 24 | /// Gets the hint. 25 | /// 26 | /// The hint to use for sorting. 27 | public string Hint { get; private set; } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /samples/ViewDiscovery/ViewDiscovery.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | Exe 4 | netcoreapp2.0 5 | 6 | 7 | 8 | %(Filename) 9 | 10 | 11 | Designer 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/Prism.Avalonia/Logging/TraceLogger.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics; 2 | 3 | namespace Prism.Logging 4 | { 5 | /// 6 | /// Implementation of that logs to .NET class. 7 | /// 8 | public class TraceLogger : ILoggerFacade 9 | { 10 | /// 11 | /// Write a new log entry with the specified category and priority. 12 | /// 13 | /// Message body to log. 14 | /// Category of the entry. 15 | /// The priority of the entry. 16 | public void Log(string message, Category category, Priority priority) 17 | { 18 | if (category == Category.Exception) 19 | { 20 | Trace.TraceError(message); 21 | } 22 | else 23 | { 24 | Trace.TraceInformation(message); 25 | } 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /tests/Prism.Avalonia.Tests/Prism.Avalonia.Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | netcoreapp2.0 4 | false 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /tests/Prism.IocContainer.Avalonia.Tests.Support/BootstrapperFixtureBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | 4 | namespace Prism.IocContainer.Avalonia.Tests.Support 5 | { 6 | public class BootstrapperFixtureBase 7 | { 8 | protected static void AssertExceptionThrownOnRun(Bootstrapper bootstrapper, Type expectedExceptionType, string expectedExceptionMessageSubstring) 9 | { 10 | bool exceptionThrown = false; 11 | try 12 | { 13 | bootstrapper.Run(); 14 | } 15 | catch (Exception ex) 16 | { 17 | Assert.AreEqual(expectedExceptionType, ex.GetType()); 18 | StringAssert.Contains(ex.Message, expectedExceptionMessageSubstring); 19 | exceptionThrown = true; 20 | } 21 | 22 | if (!exceptionThrown) 23 | { 24 | Assert.Fail("Exception not thrown."); 25 | } 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /src/Prism.Avalonia/Regions/SingleActiveRegion.cs: -------------------------------------------------------------------------------- 1 | 2 | 3 | using System.Linq; 4 | 5 | namespace Prism.Regions 6 | { 7 | /// 8 | /// Region that allows a maximum of one active view at a time. 9 | /// 10 | public class SingleActiveRegion : Region 11 | { 12 | /// 13 | /// Marks the specified view as active. 14 | /// 15 | /// The view to activate. 16 | /// If there is an active view before calling this method, 17 | /// that view will be deactivated automatically. 18 | public override void Activate(object view) 19 | { 20 | object currentActiveView = ActiveViews.FirstOrDefault(); 21 | 22 | if (currentActiveView != null && currentActiveView != view && this.Views.Contains(currentActiveView)) 23 | { 24 | base.Deactivate(currentActiveView); 25 | } 26 | base.Activate(view); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /src/Prism.Avalonia/Regions/IConfirmNavigationRequest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Prism.Regions 4 | { 5 | /// 6 | /// Provides a way for objects involved in navigation to determine if a navigation request should continue. 7 | /// 8 | public interface IConfirmNavigationRequest : INavigationAware 9 | { 10 | /// 11 | /// Determines whether this instance accepts being navigated away from. 12 | /// 13 | /// The navigation context. 14 | /// The callback to indicate when navigation can proceed. 15 | /// 16 | /// Implementors of this method do not need to invoke the callback before this method is completed, 17 | /// but they must ensure the callback is eventually invoked. 18 | /// 19 | void ConfirmNavigationRequest(NavigationContext navigationContext, Action continuationCallback); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Prism.Avalonia/Modularity/ModuleAttribute.Desktop.cs: -------------------------------------------------------------------------------- 1 | 2 | 3 | using System; 4 | 5 | namespace Prism.Modularity 6 | { 7 | /// 8 | /// Indicates that the class should be considered a named module using the 9 | /// provided module name. 10 | /// 11 | [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] 12 | public sealed class ModuleAttribute : Attribute 13 | { 14 | /// 15 | /// Gets or sets the name of the module. 16 | /// 17 | /// The name of the module. 18 | public string ModuleName { get; set; } 19 | 20 | /// 21 | /// Gets or sets the value indicating whether the module should be loaded OnDemand. 22 | /// 23 | /// When (default value), it indicates the module should be loaded as soon as it's dependencies are satisfied. 24 | /// Otherwise you should explicitily load this module via the . 25 | public bool OnDemand { get; set; } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Prism.Avalonia/Regions/ViewRegistrationException.Desktop.cs: -------------------------------------------------------------------------------- 1 | 2 | 3 | using System; 4 | using System.Runtime.Serialization; 5 | 6 | namespace Prism.Regions 7 | { 8 | /// 9 | /// Exception that's thrown when something goes wrong while Registering a View with a region name in the class. 10 | /// 11 | [Serializable] 12 | public partial class ViewRegistrationException 13 | { 14 | /// 15 | /// Initializes a new instance of the class with serialized data. 16 | /// 17 | /// The that holds the serialized 18 | /// object data about the exception being thrown. 19 | /// The that contains contextual information about the source or destination. 20 | protected ViewRegistrationException(SerializationInfo info, StreamingContext context) 21 | : base(info, context) 22 | { 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /tests/Prism.Avalonia.Tests/Mocks/MockCommand.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Input; 3 | 4 | namespace Prism.Avalonia.Tests.Mocks 5 | { 6 | internal class MockCommand : ICommand 7 | { 8 | public bool ExecuteCalled { get; set; } 9 | public bool CanExecuteReturnValue = true; 10 | public object ExecuteParameter; 11 | public object CanExecuteParameter; 12 | public int CanExecuteTimesCalled; 13 | 14 | public event EventHandler CanExecuteChanged; 15 | 16 | public void Execute(object parameter) 17 | { 18 | ExecuteCalled = true; 19 | ExecuteParameter = parameter; 20 | } 21 | 22 | public bool CanExecute(object parameter) 23 | { 24 | CanExecuteTimesCalled++; 25 | CanExecuteParameter = parameter; 26 | return CanExecuteReturnValue; 27 | } 28 | 29 | public void RaiseCanExecuteChanged() 30 | { 31 | if (this.CanExecuteChanged != null) 32 | this.CanExecuteChanged(this, EventArgs.Empty); 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /src/Prism.Avalonia/Regions/RegionMemberLifetimeAttribute.cs: -------------------------------------------------------------------------------- 1 | 2 | 3 | using System; 4 | using Prism.Regions.Behaviors; 5 | 6 | namespace Prism.Regions 7 | { 8 | /// 9 | /// When is applied to class provides data 10 | /// the can use to determine if the instance should 11 | /// be removed when it is deactivated. 12 | /// 13 | [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = true, Inherited = true )] 14 | public sealed class RegionMemberLifetimeAttribute : Attribute 15 | { 16 | /// 17 | /// Instantiates an instance of 18 | /// 19 | public RegionMemberLifetimeAttribute() 20 | { 21 | KeepAlive = true; 22 | } 23 | 24 | /// 25 | /// Determines if the region member should be kept-alive 26 | /// when deactivated. 27 | /// 28 | public bool KeepAlive { get; set; } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /samples/ModulesSample.Infrastructure/Modularity/IModuleTracker.cs: -------------------------------------------------------------------------------- 1 | namespace Prism.Avalonia.Infrastructure 2 | { 3 | /// 4 | /// Provides ability for modules to inform state of their loading 5 | /// 6 | public interface IModuleTracker 7 | { 8 | /// 9 | /// Records the module has been loaded 10 | /// 11 | /// The known name of the module 12 | void RecordModuleLoaded(string moduleName); 13 | 14 | /// 15 | /// Record the module has been constructed 16 | /// 17 | /// The known name of the module 18 | void RecordModuleConstructed(string moduleName); 19 | 20 | /// 21 | /// Record the module has been initialized 22 | /// 23 | /// The known name of the module 24 | void RecordModuleInitialized(string moduleName); 25 | } 26 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Stratocast3r 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /samples/BootstrapperShellSample/BootstrapperShellSample.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | Exe 4 | netcoreapp2.0 5 | 6 | 7 | 8 | %(Filename) 9 | 10 | 11 | Designer 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /tests/Prism.Avalonia.Tests/Mocks/MockContainerAdapter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using CommonServiceLocator; 4 | 5 | namespace Prism.Avalonia.Tests.Mocks 6 | { 7 | internal class MockContainerAdapter : ServiceLocatorImplBase 8 | { 9 | public Dictionary ResolvedInstances = new Dictionary(); 10 | 11 | protected override object DoGetInstance(Type serviceType, string key) 12 | { 13 | object resolvedInstance; 14 | if (!this.ResolvedInstances.ContainsKey(serviceType)) 15 | { 16 | resolvedInstance = Activator.CreateInstance(serviceType); 17 | this.ResolvedInstances.Add(serviceType, resolvedInstance); 18 | } 19 | else 20 | { 21 | resolvedInstance = this.ResolvedInstances[serviceType]; 22 | } 23 | 24 | return resolvedInstance; 25 | } 26 | 27 | protected override IEnumerable DoGetAllInstances(Type serviceType) 28 | { 29 | throw new System.NotImplementedException(); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /samples/ModulesSample/ModulesSample.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | Exe 4 | netcoreapp2.0 5 | 6 | 7 | 8 | %(Filename) 9 | 10 | 11 | Designer 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/Prism.Avalonia/Regions/IRegionNavigationContentLoader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Prism.Regions 4 | { 5 | /// 6 | /// Identifies the view in a region that is the target of a navigation request. 7 | /// 8 | public interface IRegionNavigationContentLoader 9 | { 10 | /// 11 | /// Gets the content to which the navigation request represented by applies. 12 | /// 13 | /// 14 | /// If none of the items in the region match the target of the navigation request, a new item 15 | /// will be created and added to the region. 16 | /// 17 | /// The region. 18 | /// The context representing the navigation request. 19 | /// The item to be the target of the navigation request. 20 | /// when a new item cannot be created for the navigation request. 21 | object LoadContent(IRegion region, NavigationContext navigationContext); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /tests/Prism.Avalonia.Tests/Mocks/MockViewsCollection.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using System.Collections.ObjectModel; 4 | using System.Collections.Specialized; 5 | using Prism.Regions; 6 | 7 | namespace Prism.Avalonia.Tests.Mocks 8 | { 9 | class MockViewsCollection : IViewsCollection 10 | { 11 | public ObservableCollection Items = new ObservableCollection(); 12 | 13 | public void Add(object view) 14 | { 15 | this.Items.Add(view); 16 | } 17 | 18 | public bool Contains(object value) 19 | { 20 | return Items.Contains(value); 21 | } 22 | 23 | public IEnumerator GetEnumerator() 24 | { 25 | return Items.GetEnumerator(); 26 | } 27 | 28 | IEnumerator IEnumerable.GetEnumerator() 29 | { 30 | return GetEnumerator(); 31 | } 32 | 33 | public event NotifyCollectionChangedEventHandler CollectionChanged 34 | { 35 | add { Items.CollectionChanged += value; } 36 | remove { Items.CollectionChanged -= value; } 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /samples/DummyModule2/View/DummyModuleView2.xaml.cs: -------------------------------------------------------------------------------- 1 | using Avalonia.Controls; 2 | using Avalonia.Markup.Xaml; 3 | using Avalonia.Threading; 4 | using Prism.Avalonia.Infrastructure.Events; 5 | using Prism.Events; 6 | 7 | namespace DummyModule2.View 8 | { 9 | public class DummyModuleView2 : UserControl 10 | { 11 | private readonly IEventAggregator eventAggregator; 12 | 13 | private TextBox regionViewTextBox; 14 | 15 | public DummyModuleView2(IEventAggregator eventAggregator) 16 | { 17 | this.eventAggregator = eventAggregator; 18 | 19 | this.InitializeComponent(); 20 | 21 | regionViewTextBox = this.FindControl("RegionViewTextBox"); 22 | eventAggregator.GetEvent().Subscribe(() => 23 | { 24 | Dispatcher.UIThread.InvokeAsync(() => 25 | { 26 | regionViewTextBox.Text += "\n EventAggregator DummyEvent triggered for DummyModule2 \r\n"; 27 | }); 28 | }); 29 | } 30 | 31 | private void InitializeComponent() 32 | { 33 | AvaloniaXamlLoader.Load(this); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tests/Prism.Autofac.Avalonia.Tests/Mocks/MockServiceLocator.cs: -------------------------------------------------------------------------------- 1 | //using System; 2 | //using System.Collections.Generic; 3 | //using Autofac; 4 | //using CommonServiceLocator; 5 | //using Prism.Regions; 6 | 7 | //namespace Prism.Autofac.Tests.Mocks 8 | //{ 9 | // public class MockServiceLocator : ServiceLocatorImplBase 10 | // { 11 | // IContainer container; 12 | 13 | // public MockServiceLocator(IContainer container) 14 | // { 15 | // this.container = container; 16 | // } 17 | 18 | // protected override IEnumerable DoGetAllInstances(Type serviceType) 19 | // { 20 | // throw new NotImplementedException(); 21 | // } 22 | 23 | // protected override object DoGetInstance(Type serviceType, string key) 24 | // { 25 | // if (serviceType == typeof(IRegionNavigationService)) 26 | // { 27 | // UnityRegionNavigationContentLoader loader = new UnityRegionNavigationContentLoader(this, this.container); 28 | // return new RegionNavigationService(this, loader, new RegionNavigationJournal()); 29 | // } 30 | 31 | // return null; 32 | // } 33 | // } 34 | //} -------------------------------------------------------------------------------- /tests/Prism.Avalonia.Tests/Modularity/ModuleAttributeFixture.Desktop.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.VisualStudio.TestTools.UnitTesting; 2 | using Prism.Modularity; 3 | 4 | namespace Prism.Avalonia.Tests.Modularity 5 | { 6 | [TestClass] 7 | public class ModuleAttributeFixture 8 | { 9 | [TestMethod] 10 | public void StartupLoadedDefaultsToTrue() 11 | { 12 | var moduleAttribute = new ModuleAttribute(); 13 | 14 | Assert.AreEqual(false, moduleAttribute.OnDemand); 15 | } 16 | 17 | [TestMethod] 18 | public void CanGetAndSetProperties() 19 | { 20 | var moduleAttribute = new ModuleAttribute(); 21 | moduleAttribute.ModuleName = "Test"; 22 | moduleAttribute.OnDemand = true; 23 | 24 | Assert.AreEqual("Test", moduleAttribute.ModuleName); 25 | Assert.AreEqual(true, moduleAttribute.OnDemand); 26 | } 27 | 28 | [TestMethod] 29 | public void ModuleDependencyAttributeStoresModuleName() 30 | { 31 | var moduleDependencyAttribute = new ModuleDependencyAttribute("Test"); 32 | 33 | Assert.AreEqual("Test", moduleDependencyAttribute.ModuleName); 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /src/Prism.Avalonia/Regions/ViewRegisteredEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Prism.Regions 4 | { 5 | /// 6 | /// Argument class used by the event when a new content is registered. 7 | /// 8 | public class ViewRegisteredEventArgs : EventArgs 9 | { 10 | /// 11 | /// Initializes the ViewRegisteredEventArgs class. 12 | /// 13 | /// The region name to which the content was registered. 14 | /// The content which was registered. 15 | public ViewRegisteredEventArgs(string regionName, Func getViewDelegate) 16 | { 17 | this.GetView = getViewDelegate; 18 | this.RegionName = regionName; 19 | } 20 | 21 | /// 22 | /// Gets the region name to which the content was registered. 23 | /// 24 | public string RegionName { get; private set; } 25 | 26 | /// 27 | /// Gets the content which was registered. 28 | /// 29 | public Func GetView { get; private set; } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /tests/Prism.DryIoc.Avalonia.Tests/DryIocBootstrapperNullLoggerFixture.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Avalonia; 3 | using Microsoft.VisualStudio.TestTools.UnitTesting; 4 | using Prism.IocContainer.Avalonia.Tests.Support; 5 | using Prism.Logging; 6 | 7 | namespace Prism.DryIoc.Avalonia.Tests 8 | { 9 | [TestClass] 10 | public class DryIocBootstrapperNullLoggerFixture : BootstrapperFixtureBase 11 | { 12 | [TestMethod] 13 | public void NullLoggerThrows() 14 | { 15 | var bootstrapper = new NullLoggerBootstrapper(); 16 | 17 | AssertExceptionThrownOnRun(bootstrapper, typeof(InvalidOperationException), "ILoggerFacade"); 18 | } 19 | 20 | internal class NullLoggerBootstrapper : DryIocBootstrapper 21 | { 22 | protected override ILoggerFacade CreateLogger() 23 | { 24 | return null; 25 | } 26 | 27 | protected override IAvaloniaObject CreateShell() 28 | { 29 | throw new NotImplementedException(); 30 | } 31 | 32 | protected override void InitializeShell() 33 | { 34 | throw new NotImplementedException(); 35 | } 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /tests/Prism.Autofac.Avalonia.Tests/AutofacBootstrapperNullLoggerFixture.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Avalonia; 3 | using Microsoft.VisualStudio.TestTools.UnitTesting; 4 | using Prism.IocContainer.Avalonia.Tests.Support; 5 | using Prism.Logging; 6 | 7 | namespace Prism.Autofac.Avalonia.Tests 8 | { 9 | [TestClass] 10 | public class AutofacBootstrapperNullLoggerFixture : BootstrapperFixtureBase 11 | { 12 | [TestMethod] 13 | public void NullLoggerThrows() 14 | { 15 | var bootstrapper = new NullLoggerBootstrapper(); 16 | 17 | AssertExceptionThrownOnRun(bootstrapper, typeof(InvalidOperationException), "ILoggerFacade"); 18 | } 19 | 20 | internal class NullLoggerBootstrapper : AutofacBootstrapper 21 | { 22 | protected override ILoggerFacade CreateLogger() 23 | { 24 | return null; 25 | } 26 | 27 | protected override IAvaloniaObject CreateShell() 28 | { 29 | throw new NotImplementedException(); 30 | } 31 | 32 | protected override void InitializeShell() 33 | { 34 | throw new NotImplementedException(); 35 | } 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Prism.Avalonia/Events/WeakDelegatesManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace Prism.Events 6 | { 7 | internal class WeakDelegatesManager 8 | { 9 | private readonly List listeners = new List(); 10 | 11 | public void AddListener(Delegate listener) 12 | { 13 | this.listeners.Add(new DelegateReference(listener, false)); 14 | } 15 | 16 | public void RemoveListener(Delegate listener) 17 | { 18 | this.listeners.RemoveAll(reference => 19 | { 20 | //Remove the listener, and prune collected listeners 21 | Delegate target = reference.Target; 22 | return listener.Equals(target) || target == null; 23 | }); 24 | } 25 | 26 | public void Raise(params object[] args) 27 | { 28 | this.listeners.RemoveAll(listener => listener.Target == null); 29 | 30 | foreach (Delegate handler in this.listeners.ToList().Select(listener => listener.Target).Where(listener => listener != null)) 31 | { 32 | handler.DynamicInvoke(args); 33 | } 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Prism.Avalonia/Modularity/ModuleDependencyAttribute.Desktop.cs: -------------------------------------------------------------------------------- 1 | 2 | 3 | using System; 4 | 5 | namespace Prism.Modularity 6 | { 7 | /// 8 | /// Specifies that the current module has a dependency on another module. This attribute should be used on classes that implement . 9 | /// 10 | [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] 11 | public sealed class ModuleDependencyAttribute : Attribute 12 | { 13 | private readonly string _moduleName; 14 | 15 | /// 16 | /// Initializes a new instance of . 17 | /// 18 | /// The name of the module that this module is dependant upon. 19 | public ModuleDependencyAttribute(string moduleName) 20 | { 21 | _moduleName = moduleName; 22 | } 23 | 24 | /// 25 | /// Gets the name of the module that this module is dependant upon. 26 | /// 27 | /// The name of the module that this module is dependant upon. 28 | public string ModuleName 29 | { 30 | get { return _moduleName; } 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Prism.Avalonia/Regions/IRegionNavigationService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Prism.Regions 4 | { 5 | /// 6 | /// Provides navigation for regions. 7 | /// 8 | public interface IRegionNavigationService : INavigateAsync 9 | { 10 | /// 11 | /// Gets or sets the region owning this service. 12 | /// 13 | /// A Region. 14 | IRegion Region { get; set; } 15 | 16 | /// 17 | /// Gets the journal. 18 | /// 19 | /// The journal. 20 | IRegionNavigationJournal Journal { get; } 21 | 22 | /// 23 | /// Raised when the region is about to be navigated to content. 24 | /// 25 | event EventHandler Navigating; 26 | 27 | /// 28 | /// Raised when the region is navigated to content. 29 | /// 30 | event EventHandler Navigated; 31 | 32 | /// 33 | /// Raised when a navigation request fails. 34 | /// 35 | event EventHandler NavigationFailed; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /tests/Prism.Avalonia.Tests/Modularity/ModuleCatalogXaml/SimpleModuleCatalog.xaml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | ModuleW 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /tests/Prism.DryIoc.Avalonia.Tests/DryIocBootstrapperNullContainerFixture.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Avalonia; 3 | using DryIoc; 4 | using Microsoft.VisualStudio.TestTools.UnitTesting; 5 | using Prism.IocContainer.Avalonia.Tests.Support; 6 | 7 | namespace Prism.DryIoc.Avalonia.Tests 8 | { 9 | [TestClass] 10 | public class DryIocBootstrapperNullContainerFixture : BootstrapperFixtureBase 11 | { 12 | [TestMethod] 13 | public void RunThrowsWhenNullContainerCreated() 14 | { 15 | var bootstrapper = new NullContainerBootstrapper(); 16 | 17 | AssertExceptionThrownOnRun(bootstrapper, typeof(InvalidOperationException), "IContainer"); 18 | } 19 | 20 | private class NullContainerBootstrapper : DryIocBootstrapper 21 | { 22 | protected override IContainer CreateContainer() 23 | { 24 | return null; 25 | } 26 | 27 | protected override IAvaloniaObject CreateShell() 28 | { 29 | throw new NotImplementedException(); 30 | } 31 | 32 | protected override void InitializeShell() 33 | { 34 | throw new NotImplementedException(); 35 | } 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Prism.Avalonia/Modularity/ModuleManager.Desktop.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Prism.Modularity 4 | { 5 | /// 6 | /// Component responsible for coordinating the modules' type loading and module initialization process. 7 | /// 8 | public partial class ModuleManager 9 | { 10 | /// 11 | /// Returns the list of registered instances that will be 12 | /// used to load the types of modules. 13 | /// 14 | /// The module type loaders. 15 | public virtual IEnumerable ModuleTypeLoaders 16 | { 17 | get 18 | { 19 | if (this.typeLoaders == null) 20 | { 21 | this.typeLoaders = new List 22 | { 23 | new FileModuleTypeLoader() 24 | }; 25 | } 26 | 27 | return this.typeLoaders; 28 | } 29 | 30 | set 31 | { 32 | this.typeLoaders = value; 33 | } 34 | } 35 | 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Prism.Avalonia/Regions/AllActiveRegion.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Prism.Avalonia.Properties; 3 | using Prism.Properties; 4 | 5 | namespace Prism.Regions 6 | { 7 | /// 8 | /// Region that keeps all the views in it as active. Deactivation of views is not allowed. 9 | /// 10 | public class AllActiveRegion : Region 11 | { 12 | /// 13 | /// Gets a readonly view of the collection of all the active views in the region. These are all the added views. 14 | /// 15 | /// An of all the active views. 16 | public override IViewsCollection ActiveViews 17 | { 18 | get { return Views; } 19 | } 20 | 21 | /// 22 | /// Deactive is not valid in this Region. This method will always throw . 23 | /// 24 | /// The view to deactivate. 25 | /// Every time this method is called. 26 | public override void Deactivate(object view) 27 | { 28 | throw new InvalidOperationException(Resources.DeactiveNotPossibleException); 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /src/Prism.Avalonia/Regions/INavigationAware.cs: -------------------------------------------------------------------------------- 1 | namespace Prism.Regions 2 | { 3 | /// 4 | /// Provides a way for objects involved in navigation to be notified of navigation activities. 5 | /// 6 | public interface INavigationAware 7 | { 8 | /// 9 | /// Called when the implementer has been navigated to. 10 | /// 11 | /// The navigation context. 12 | void OnNavigatedTo(NavigationContext navigationContext); 13 | 14 | /// 15 | /// Called to determine if this instance can handle the navigation request. 16 | /// 17 | /// The navigation context. 18 | /// 19 | /// if this instance accepts the navigation request; otherwise, . 20 | /// 21 | bool IsNavigationTarget(NavigationContext navigationContext); 22 | 23 | /// 24 | /// Called when the implementer is being navigated away from. 25 | /// 26 | /// The navigation context. 27 | void OnNavigatedFrom(NavigationContext navigationContext); 28 | } 29 | } -------------------------------------------------------------------------------- /src/Prism.Avalonia/Modularity/IModuleManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Prism.Modularity 4 | { 5 | /// 6 | /// Defines the interface for the service that will retrieve and initialize the application's modules. 7 | /// 8 | public interface IModuleManager 9 | { 10 | /// 11 | /// Initializes the modules marked as on the . 12 | /// 13 | void Run(); 14 | 15 | /// 16 | /// Loads and initializes the module on the with the name . 17 | /// 18 | /// Name of the module requested for initialization. 19 | void LoadModule(string moduleName); 20 | 21 | /// 22 | /// Raised repeatedly to provide progress as modules are downloaded. 23 | /// 24 | event EventHandler ModuleDownloadProgressChanged; 25 | 26 | /// 27 | /// Raised when a module is loaded or fails to load. 28 | /// 29 | event EventHandler LoadModuleCompleted; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /tests/Prism.DryIoc.Avalonia.Tests/DryIocBootstrapperNullModuleCatalogFixture.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Avalonia; 3 | using Microsoft.VisualStudio.TestTools.UnitTesting; 4 | using Prism.IocContainer.Avalonia.Tests.Support; 5 | using Prism.Modularity; 6 | 7 | namespace Prism.DryIoc.Avalonia.Tests 8 | { 9 | [TestClass] 10 | public class DryIocBootstrapperNullModuleCatalogFixture : BootstrapperFixtureBase 11 | { 12 | [TestMethod] 13 | public void NullModuleCatalogThrowsOnDefaultModuleInitialization() 14 | { 15 | var bootstrapper = new NullModuleCatalogBootstrapper(); 16 | 17 | AssertExceptionThrownOnRun(bootstrapper, typeof(InvalidOperationException), "IModuleCatalog"); 18 | } 19 | 20 | private class NullModuleCatalogBootstrapper : DryIocBootstrapper 21 | { 22 | protected override IModuleCatalog CreateModuleCatalog() 23 | { 24 | return null; 25 | } 26 | 27 | protected override IAvaloniaObject CreateShell() 28 | { 29 | throw new NotImplementedException(); 30 | } 31 | 32 | protected override void InitializeShell() 33 | { 34 | throw new NotImplementedException(); 35 | } 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /samples/ModulesSample/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using Avalonia; 2 | using Avalonia.Controls; 3 | using Avalonia.Diagnostics; 4 | using Avalonia.Logging.Serilog; 5 | using Avalonia.Markup.Xaml; 6 | using Serilog; 7 | 8 | namespace ModulesSample 9 | { 10 | class App : Application 11 | { 12 | public static AppBuilder BuildAvaloniaApp() => AppBuilder.Configure().UsePlatformDetect() 13 | .SetupWithoutStarting(); 14 | 15 | public override void Initialize() 16 | { 17 | AvaloniaXamlLoader.Load(this); 18 | base.Initialize(); 19 | } 20 | 21 | static void Main(string[] args) 22 | { 23 | InitializeLogging(); 24 | 25 | Bootstrapper bs = new Bootstrapper(); 26 | 27 | bs.Run(); 28 | } 29 | 30 | public static void AttachDevTools(Window window) 31 | { 32 | #if DEBUG 33 | DevTools.Attach(window); 34 | #endif 35 | } 36 | 37 | private static void InitializeLogging() 38 | { 39 | #if DEBUG 40 | SerilogLogger.Initialize(new LoggerConfiguration() 41 | .MinimumLevel.Warning() 42 | .WriteTo.Trace(outputTemplate: "{Area}: {Message}") 43 | .CreateLogger()); 44 | #endif 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /tests/Prism.Autofac.Avalonia.Tests/AutofacBootstrapperNullModuleCatalogFixture.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Avalonia; 3 | using Microsoft.VisualStudio.TestTools.UnitTesting; 4 | using Prism.IocContainer.Avalonia.Tests.Support; 5 | using Prism.Modularity; 6 | 7 | namespace Prism.Autofac.Avalonia.Tests 8 | { 9 | [TestClass] 10 | public class AutofacBootstrapperNullModuleCatalogFixture : BootstrapperFixtureBase 11 | { 12 | [TestMethod] 13 | public void NullModuleCatalogThrowsOnDefaultModuleInitialization() 14 | { 15 | var bootstrapper = new NullModuleCatalogBootstrapper(); 16 | 17 | AssertExceptionThrownOnRun(bootstrapper, typeof(InvalidOperationException), "IModuleCatalog"); 18 | } 19 | 20 | private class NullModuleCatalogBootstrapper : AutofacBootstrapper 21 | { 22 | protected override IModuleCatalog CreateModuleCatalog() 23 | { 24 | return null; 25 | } 26 | 27 | protected override IAvaloniaObject CreateShell() 28 | { 29 | throw new NotImplementedException(); 30 | } 31 | 32 | protected override void InitializeShell() 33 | { 34 | throw new NotImplementedException(); 35 | } 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /tests/Prism.Avalonia.Tests/Mocks/MockRegionManagerAccessor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Avalonia; 3 | using Prism.Regions; 4 | 5 | namespace Prism.Avalonia.Tests.Mocks 6 | { 7 | internal class MockRegionManagerAccessor : IRegionManagerAccessor 8 | { 9 | public Func GetRegionName; 10 | public Func GetRegionManager; 11 | 12 | public event EventHandler UpdatingRegions; 13 | 14 | string IRegionManagerAccessor.GetRegionName(AvaloniaObject element) 15 | { 16 | return this.GetRegionName(element); 17 | } 18 | 19 | IRegionManager IRegionManagerAccessor.GetRegionManager(AvaloniaObject element) 20 | { 21 | if (this.GetRegionManager != null) 22 | { 23 | return this.GetRegionManager(element); 24 | } 25 | 26 | return null; 27 | } 28 | 29 | public void UpdateRegions() 30 | { 31 | if (this.UpdatingRegions != null) 32 | { 33 | this.UpdatingRegions(this, EventArgs.Empty); 34 | } 35 | } 36 | 37 | public int GetSubscribersCount() 38 | { 39 | return this.UpdatingRegions != null ? this.UpdatingRegions.GetInvocationList().Length : 0; 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /src/Prism.Avalonia/Common/MvvmHelpers.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using Avalonia.Controls; 5 | 6 | namespace Prism.Common 7 | { 8 | public static class MvvmHelpers 9 | { 10 | public static void ViewAndViewModelAction(object view, Action action) where T : class 11 | { 12 | T viewAsT = view as T; 13 | if (viewAsT != null) 14 | action(viewAsT); 15 | var element = view as Control; 16 | if (element != null) 17 | { 18 | var viewModelAsT = element.DataContext as T; 19 | if (viewModelAsT != null) 20 | { 21 | action(viewModelAsT); 22 | } 23 | } 24 | } 25 | 26 | public static T GetImplementerFromViewOrViewModel(object view) where T : class 27 | { 28 | T viewAsT = view as T; 29 | if (viewAsT != null) 30 | { 31 | return viewAsT; 32 | } 33 | 34 | var element = view as Control; 35 | if (element != null) 36 | { 37 | var vmAsT = element.DataContext as T; 38 | return vmAsT; 39 | } 40 | 41 | return null; 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Prism.Avalonia/Regions/RegionNavigationJournalEntry.cs: -------------------------------------------------------------------------------- 1 | 2 | 3 | using System; 4 | using System.Globalization; 5 | 6 | namespace Prism.Regions 7 | { 8 | /// 9 | /// An entry in an IRegionNavigationJournal representing the URI navigated to. 10 | /// 11 | public class RegionNavigationJournalEntry : IRegionNavigationJournalEntry 12 | { 13 | /// 14 | /// Gets or sets the URI. 15 | /// 16 | /// The URI. 17 | public Uri Uri { get; set; } 18 | 19 | /// 20 | /// Gets or sets the NavigationParameters instance. 21 | /// 22 | public NavigationParameters Parameters { get; set; } 23 | 24 | /// 25 | /// Returns a that represents this instance. 26 | /// 27 | /// 28 | /// A that represents this instance. 29 | /// 30 | public override string ToString() 31 | { 32 | if (this.Uri != null) 33 | { 34 | return string.Format(CultureInfo.CurrentCulture, "RegionNavigationJournalEntry:'{0}'", this.Uri.ToString()); 35 | } 36 | 37 | return base.ToString(); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /samples/ViewDiscovery/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Avalonia; 3 | using Avalonia.Controls; 4 | using Avalonia.Diagnostics; 5 | using Avalonia.Logging.Serilog; 6 | using Avalonia.Themes.Default; 7 | using Avalonia.Markup.Xaml; 8 | using Serilog; 9 | 10 | namespace ViewDiscovery 11 | { 12 | class App : Application 13 | { 14 | public static AppBuilder BuildAvaloniaApp() => AppBuilder.Configure().UsePlatformDetect() 15 | .SetupWithoutStarting(); 16 | 17 | public override void Initialize() 18 | { 19 | AvaloniaXamlLoader.Load(this); 20 | base.Initialize(); 21 | } 22 | 23 | static void Main(string[] args) 24 | { 25 | InitializeLogging(); 26 | 27 | Bootstrapper bs = new Bootstrapper(); 28 | 29 | bs.Run(); 30 | } 31 | 32 | public static void AttachDevTools(Window window) 33 | { 34 | #if DEBUG 35 | DevTools.Attach(window); 36 | #endif 37 | } 38 | 39 | private static void InitializeLogging() 40 | { 41 | #if DEBUG 42 | SerilogLogger.Initialize(new LoggerConfiguration() 43 | .MinimumLevel.Warning() 44 | .WriteTo.Trace(outputTemplate: "{Area}: {Message}") 45 | .CreateLogger()); 46 | #endif 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/Prism.Avalonia/Modularity/ModuleState.cs: -------------------------------------------------------------------------------- 1 | namespace Prism.Modularity 2 | { 3 | /// 4 | /// Defines the states a can be in, with regards to the module loading and initialization process. 5 | /// 6 | public enum ModuleState 7 | { 8 | /// 9 | /// Initial state for s. The is defined, 10 | /// but it has not been loaded, retrieved or initialized yet. 11 | /// 12 | NotStarted, 13 | 14 | /// 15 | /// The assembly that contains the type of the module is currently being loaded by an instance of a 16 | /// . 17 | /// 18 | LoadingTypes, 19 | 20 | /// 21 | /// The assembly that holds the Module is present. This means the type of the can be instantiated and initialized. 22 | /// 23 | ReadyForInitialization, 24 | 25 | /// 26 | /// The module is currently Initializing, by the 27 | /// 28 | Initializing, 29 | 30 | /// 31 | /// The module is initialized and ready to be used. 32 | /// 33 | Initialized 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /samples/BootstrapperShellSample/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Avalonia; 3 | using Avalonia.Controls; 4 | using Avalonia.Diagnostics; 5 | using Avalonia.Logging.Serilog; 6 | using Avalonia.Themes.Default; 7 | using Avalonia.Markup.Xaml; 8 | using CommonServiceLocator; 9 | using DryIoc; 10 | using Serilog; 11 | 12 | namespace BootstrapperShellSample 13 | { 14 | class App : Application 15 | { 16 | public static AppBuilder BuildAvaloniaApp() => AppBuilder.Configure().UsePlatformDetect().SetupWithoutStarting(); 17 | 18 | public override void Initialize() 19 | { 20 | AvaloniaXamlLoader.Load(this); 21 | base.Initialize(); 22 | } 23 | 24 | static void Main(string[] args) 25 | { 26 | InitializeLogging(); 27 | 28 | Bootstrapper bs = new Bootstrapper(); 29 | 30 | bs.Run(); 31 | } 32 | 33 | public static void AttachDevTools(Window window) 34 | { 35 | #if DEBUG 36 | DevTools.Attach(window); 37 | #endif 38 | } 39 | 40 | private static void InitializeLogging() 41 | { 42 | #if DEBUG 43 | SerilogLogger.Initialize(new LoggerConfiguration() 44 | .MinimumLevel.Warning() 45 | .WriteTo.Trace(outputTemplate: "{Area}: {Message}") 46 | .CreateLogger()); 47 | #endif 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Prism.Avalonia 2 | Prism (https://github.com/PrismLibrary/Prism) framework support for Avalonia UI. 3 | 4 | This library actually copies functionality of Prism for WPF implementation, which can be found here: 5 | https://github.com/PrismLibrary/Prism/tree/master/Source/Wpf 6 | 7 | Logic and approach for development of your applications remained the same as it was for Prism.Wpf library. 8 | 9 | Also, I should say that because this port was made in a few days in a rush-mode without deep knowledge 10 | of Avalonia's internal mechanisms and because of differences in runtime platforms, not everything was 11 | ported (list below), in addition of course you can confront with various bugs. 12 | I will use this port in my internalwork projects, so by developing applications I'll fix bugs 13 | or invalid behaviours which can occur on my path, but issues and pull requests are welcome too! 14 | 15 | Not ported/supported features and other problems: 16 | - Prism.Avalonia not supports ability to bind Region to ItemsSource/Selector element 17 | - ViewInjection for regions will not work 18 | - DirectoryCatalog implementation of ModuleCatalog 19 | - Not all tests are reproducible because of runtime or avalonia capabilities 20 | 21 | | ModulesSample on Ubuntu 16.04 | ModulesSample on Windows 10 | 22 | |---|---| 23 | | | | 24 | -------------------------------------------------------------------------------- /src/Prism.Avalonia/Modularity/ModuleDependencyConfigurationElement.Desktop.cs: -------------------------------------------------------------------------------- 1 | using System.Configuration; 2 | 3 | namespace Prism.Modularity 4 | { 5 | /// 6 | /// A for module dependencies. 7 | /// 8 | public class ModuleDependencyConfigurationElement : ConfigurationElement 9 | { 10 | /// 11 | /// Initializes a new instance of . 12 | /// 13 | public ModuleDependencyConfigurationElement() 14 | { 15 | } 16 | 17 | /// 18 | /// Initializes a new instance of . 19 | /// 20 | /// A module name. 21 | public ModuleDependencyConfigurationElement(string moduleName) 22 | { 23 | base["moduleName"] = moduleName; 24 | } 25 | 26 | /// 27 | /// Gets or sets the name of a module antoher module depends on. 28 | /// 29 | /// The name of a module antoher module depends on. 30 | [ConfigurationProperty("moduleName", IsRequired = true, IsKey = true)] 31 | public string ModuleName 32 | { 33 | get { return (string)base["moduleName"]; } 34 | set { base["moduleName"] = value; } 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /tests/Prism.DryIoc.Avalonia.Tests/DryIocBootstrapperRegisterForNavigationFixture.cs: -------------------------------------------------------------------------------- 1 | using CommonServiceLocator; 2 | using DryIoc; 3 | using Microsoft.VisualStudio.TestTools.UnitTesting; 4 | using Prism.IocContainer.Avalonia.Tests.Support; 5 | 6 | namespace Prism.DryIoc.Avalonia.Tests 7 | { 8 | [TestClass] 9 | public class DryIocBootstrapperRegisterForNavigationFixture : BootstrapperFixtureBase 10 | { 11 | [TestMethod] 12 | public void RunCheckIfViewRegisteredForNavigationCanBeResolvedTroughServiceLocatorWithObjectServiceType() 13 | { 14 | var bootstrapper = new RegisterForNavigationBootstrapper(); 15 | bootstrapper.Run(); 16 | IServiceLocator serviceLocator = bootstrapper.Container.Resolve(); 17 | object viewInstance = serviceLocator.GetInstance(nameof(NavigateView)); 18 | 19 | Assert.IsNotNull(viewInstance); 20 | Assert.IsInstanceOfType(viewInstance, typeof(NavigateView)); 21 | } 22 | 23 | private class RegisterForNavigationBootstrapper : DryIocBootstrapper 24 | { 25 | protected override void ConfigureContainer() 26 | { 27 | base.ConfigureContainer(); 28 | Container.RegisterTypeForNavigation(); 29 | } 30 | } 31 | 32 | public class NavigateView 33 | { 34 | 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Prism.Avalonia/Extensions/CollectionExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace System.Collections.ObjectModel 4 | { 5 | /// 6 | /// Class that provides extension methods to Collection 7 | /// 8 | public static class CollectionExtensions 9 | { 10 | /// 11 | /// Add a range of items to a collection. 12 | /// 13 | /// Type of objects within the collection. 14 | /// The collection to add items to. 15 | /// The items to add to the collection. 16 | /// The collection. 17 | /// An is thrown if or is . 18 | public static Collection AddRange(this Collection collection, IEnumerable items) 19 | { 20 | if (collection == null) 21 | throw new ArgumentNullException(nameof(collection)); 22 | if (items == null) 23 | throw new ArgumentNullException(nameof(items)); 24 | 25 | foreach (var each in items) 26 | { 27 | collection.Add(each); 28 | } 29 | 30 | return collection; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Prism.Avalonia/Regions/IRegionBehaviorCollection.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Prism.Regions 4 | { 5 | /// 6 | /// Defines the interface for a collection of classes on a Region. 7 | /// 8 | public interface IRegionBehaviorCollection : IEnumerable> 9 | { 10 | 11 | /// 12 | /// Adds a to the collection, using the specified key as an indexer. 13 | /// 14 | /// 15 | /// The key that specifies the type of that's added. 16 | /// 17 | /// The to add. 18 | void Add(string key, IRegionBehavior regionBehavior); 19 | 20 | /// 21 | /// Checks if a with the specified key is already present. 22 | /// 23 | /// The key to use to find a particular . 24 | /// 25 | bool ContainsKey(string key); 26 | 27 | /// 28 | /// Gets the with the specified key. 29 | /// 30 | /// The registered 31 | IRegionBehavior this[string key]{ get; } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Prism.Avalonia/Regions/IRegionManagerAccessor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows; 3 | using Avalonia; 4 | 5 | namespace Prism.Regions 6 | { 7 | /// 8 | /// Provides an abstraction on top of the RegionManager static members. 9 | /// 10 | public interface IRegionManagerAccessor 11 | { 12 | /// 13 | /// Notification used by attached behaviors to update the region managers appropriatelly if needed to. 14 | /// 15 | /// This event uses weak references to the event handler to prevent this static event of keeping the 16 | /// target element longer than expected. 17 | event EventHandler UpdatingRegions; 18 | 19 | /// 20 | /// Gets the value for the RegionName attached property. 21 | /// 22 | /// The object to adapt. This is typically a container (i.e a control). 23 | /// The name of the region that should be created when 24 | /// the RegionManager is also set in this element. 25 | string GetRegionName(AvaloniaObject element); 26 | 27 | /// 28 | /// Gets the value of the RegionName attached property. 29 | /// 30 | /// The target element. 31 | /// The attached to the element. 32 | IRegionManager GetRegionManager(AvaloniaObject element); 33 | } 34 | } -------------------------------------------------------------------------------- /tests/Prism.Avalonia.Tests/Regions/RegionBehaviorCollectionFixture.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.VisualStudio.TestTools.UnitTesting; 2 | using Prism.Avalonia.Tests.Mocks; 3 | using Prism.Regions; 4 | 5 | namespace Prism.Avalonia.Tests.Regions 6 | { 7 | [TestClass] 8 | public class RegionBehaviorCollectionFixture 9 | { 10 | [TestMethod] 11 | public void CanAttachRegionBehaviors() 12 | { 13 | RegionBehaviorCollection behaviorCollection = new RegionBehaviorCollection(new MockPresentationRegion()); 14 | 15 | var mock1 = new MockRegionBehavior(); 16 | bool mock1Attached = false; 17 | mock1.OnAttach = () => mock1Attached = true; 18 | behaviorCollection.Add("Mock1", mock1); 19 | 20 | var mock2 = new MockRegionBehavior(); 21 | bool mock2Attached = false; 22 | mock2.OnAttach = () => mock2Attached = true; 23 | behaviorCollection.Add("Mock2", mock2); 24 | 25 | Assert.IsTrue(mock1Attached); 26 | Assert.IsTrue(mock2Attached); 27 | } 28 | 29 | [TestMethod] 30 | public void ShouldAddRegionWhenAddingBehavior() 31 | { 32 | var region = new MockPresentationRegion(); 33 | RegionBehaviorCollection behaviorCollection = new RegionBehaviorCollection(region); 34 | var behavior = new MockRegionBehavior(); 35 | 36 | behaviorCollection.Add("Mock", behavior); 37 | 38 | Assert.IsNotNull(behavior.Region); 39 | Assert.AreSame(region, behavior.Region); 40 | } 41 | 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Prism.Avalonia/Regions/RegionNavigationEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Prism.Regions 4 | { 5 | /// 6 | /// EventArgs used with the Navigated event. 7 | /// 8 | public class RegionNavigationEventArgs : EventArgs 9 | { 10 | /// 11 | /// Initializes a new instance of the class. 12 | /// 13 | /// The navigation context. 14 | public RegionNavigationEventArgs(NavigationContext navigationContext) 15 | { 16 | if (navigationContext == null) 17 | throw new ArgumentNullException(nameof(navigationContext)); 18 | 19 | this.NavigationContext = navigationContext; 20 | } 21 | 22 | /// 23 | /// Gets the navigation context. 24 | /// 25 | /// The navigation context. 26 | public NavigationContext NavigationContext { get; private set; } 27 | 28 | /// 29 | /// Gets the navigation URI 30 | /// 31 | /// The URI. 32 | /// 33 | /// This is a convenience accessor around NavigationContext.Uri. 34 | /// 35 | public Uri Uri 36 | { 37 | get 38 | { 39 | if (this.NavigationContext != null) 40 | { 41 | return this.NavigationContext.Uri; 42 | } 43 | 44 | return null; 45 | } 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /samples/DummyModule/DummyModule.cs: -------------------------------------------------------------------------------- 1 | using System.Threading; 2 | using DummyModule.View; 3 | using Prism.Avalonia.Infrastructure; 4 | using Prism.Avalonia.Infrastructure.Events; 5 | using Prism.Events; 6 | using Prism.Logging; 7 | using Prism.Modularity; 8 | using Prism.Regions; 9 | 10 | namespace DummyModule 11 | { 12 | public class DummyModule : IModule 13 | { 14 | private readonly ILoggerFacade logger; 15 | private readonly IModuleTracker moduleTracker; 16 | private readonly IEventAggregator eventAggregator; 17 | private readonly IRegionManager regionManager; 18 | 19 | public DummyModule(ILoggerFacade logger, IModuleTracker moduleTracker, IEventAggregator eventAggregator, 20 | IRegionManager regionManager) 21 | { 22 | this.logger = logger; 23 | this.moduleTracker = moduleTracker; 24 | this.eventAggregator = eventAggregator; 25 | this.regionManager = regionManager; 26 | } 27 | 28 | private void DummyEventPublisher() 29 | { 30 | while (true) 31 | { 32 | Thread.Sleep(2500); 33 | eventAggregator.GetEvent().Publish(); 34 | } 35 | } 36 | 37 | public void Initialize() 38 | { 39 | Thread thread = new Thread(new ThreadStart(DummyEventPublisher)); 40 | thread.Start(); 41 | 42 | regionManager.RegisterViewWithRegion("Region1", typeof(DummyModuleView)); 43 | 44 | this.moduleTracker.RecordModuleInitialized(KnownModuleNames.ModuleDummy); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Prism.Avalonia/Regions/UpdateRegionsException.cs: -------------------------------------------------------------------------------- 1 | 2 | 3 | using System; 4 | 5 | namespace Prism.Regions 6 | { 7 | /// 8 | /// Represents errors that occured during the regions' update. 9 | /// 10 | public partial class UpdateRegionsException : Exception 11 | { 12 | /// 13 | /// Initializes a new instance of the 14 | /// 15 | public UpdateRegionsException() 16 | { 17 | } 18 | 19 | /// 20 | /// Initializes a new instance of the class with a specified error message. 21 | /// 22 | /// The message that describes the error. 23 | public UpdateRegionsException(string message) 24 | : base(message) 25 | { 26 | } 27 | 28 | /// 29 | /// Initializes a new instance of the class with a specified error message and a reference 30 | /// to the inner exception that is the cause of this exception. 31 | /// 32 | /// The error message that explains the reason for the exception. 33 | /// The exception that is the cause of the current exception, or a null reference 34 | /// (Nothing in Visual Basic) if no inner exception is specified. 35 | public UpdateRegionsException(string message, Exception inner) 36 | : base(message, inner) 37 | { 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Prism.Avalonia/Regions/Behaviors/RegionCreationException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Prism.Regions.Behaviors 4 | { 5 | /// 6 | /// Represents errors that occured during region creation. 7 | /// 8 | public partial class RegionCreationException : Exception 9 | { 10 | /// 11 | /// Initializes a new instance of the 12 | /// 13 | public RegionCreationException() 14 | { 15 | } 16 | 17 | /// 18 | /// Initializes a new instance of the class with a specified error message. 19 | /// 20 | /// The message that describes the error. 21 | public RegionCreationException(string message) 22 | : base(message) 23 | { 24 | } 25 | 26 | /// 27 | /// Initializes a new instance of the class with a specified error message and a reference 28 | /// to the inner exception that is the cause of this exception. 29 | /// 30 | /// The error message that explains the reason for the exception. 31 | /// The exception that is the cause of the current exception, or a null reference 32 | /// (Nothing in Visual Basic) if no inner exception is specified. 33 | public RegionCreationException(string message, Exception inner) 34 | : base(message, inner) 35 | { 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /tests/Prism.Avalonia.Tests/Mocks/MockServiceLocator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CommonServiceLocator; 3 | 4 | namespace Prism.Avalonia.Tests.Mocks 5 | { 6 | internal class MockServiceLocator : IServiceLocator 7 | { 8 | public Func GetInstance; 9 | public Func GetService; 10 | 11 | object IServiceLocator.GetInstance(Type serviceType) 12 | { 13 | if (this.GetInstance != null) 14 | return this.GetInstance(serviceType); 15 | 16 | return null; 17 | } 18 | 19 | object IServiceProvider.GetService(Type serviceType) 20 | { 21 | if (this.GetService != null) 22 | return this.GetService(serviceType); 23 | 24 | return null; 25 | } 26 | 27 | System.Collections.Generic.IEnumerable IServiceLocator.GetAllInstances() 28 | { 29 | throw new NotImplementedException(); 30 | } 31 | 32 | System.Collections.Generic.IEnumerable IServiceLocator.GetAllInstances(Type serviceType) 33 | { 34 | throw new NotImplementedException(); 35 | } 36 | 37 | TService IServiceLocator.GetInstance(string key) 38 | { 39 | throw new NotImplementedException(); 40 | } 41 | 42 | TService IServiceLocator.GetInstance() 43 | { 44 | return (TService)GetInstance(typeof(TService)); 45 | } 46 | 47 | object IServiceLocator.GetInstance(Type serviceType, string key) 48 | { 49 | throw new NotImplementedException(); 50 | } 51 | } 52 | } -------------------------------------------------------------------------------- /src/Prism.Avalonia/Modularity/IModuleTypeLoader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Prism.Modularity 4 | { 5 | /// 6 | /// Defines the interface for moduleTypeLoaders 7 | /// 8 | public interface IModuleTypeLoader 9 | { 10 | /// 11 | /// Evaluates the property to see if the current typeloader will be able to retrieve the . 12 | /// 13 | /// Module that should have it's type loaded. 14 | /// if the current typeloader is able to retrieve the module, otherwise . 15 | bool CanLoadModuleType(ModuleInfo moduleInfo); 16 | 17 | /// 18 | /// Retrieves the . 19 | /// 20 | /// Module that should have it's type loaded. 21 | void LoadModuleType(ModuleInfo moduleInfo); 22 | 23 | /// 24 | /// Raised repeatedly to provide progress as modules are downloaded in the background. 25 | /// 26 | event EventHandler ModuleDownloadProgressChanged; 27 | 28 | /// 29 | /// Raised when a module is loaded or fails to load. 30 | /// 31 | /// 32 | /// This event is raised once per ModuleInfo instance requested in . 33 | /// 34 | event EventHandler LoadModuleCompleted; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Prism.Avalonia/Prism.Avalonia.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | netstandard2.0 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | True 15 | True 16 | Resources.resx 17 | 18 | 19 | 20 | 21 | PublicResXFileCodeGenerator 22 | Resources.Designer.cs 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | ..\..\..\..\..\..\..\..\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.2\System.Configuration.dll 31 | 32 | 33 | C:\Users\Sergey\.nuget\packages\system.configuration.configurationmanager\4.4.0\ref\netstandard2.0\System.Configuration.ConfigurationManager.dll 34 | 35 | 36 | -------------------------------------------------------------------------------- /src/Prism.Avalonia/Regions/ViewRegistrationException.cs: -------------------------------------------------------------------------------- 1 | 2 | 3 | using System; 4 | 5 | namespace Prism.Regions 6 | { 7 | /// 8 | /// Exception that's thrown when something goes wrong while Registering a View with a region name in the class. 9 | /// 10 | public partial class ViewRegistrationException : Exception 11 | { 12 | // 13 | // For guidelines regarding the creation of new exception types, see 14 | // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpgenref/html/cpconerrorraisinghandlingguidelines.asp 15 | // and 16 | // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncscol/html/csharp07192001.asp 17 | // 18 | 19 | /// 20 | /// Initializes a new instance of the class. 21 | /// 22 | public ViewRegistrationException() 23 | { 24 | } 25 | 26 | /// 27 | /// Initializes a new instance of the class. 28 | /// 29 | /// The exception message. 30 | public ViewRegistrationException(string message) : base(message) 31 | { 32 | } 33 | 34 | /// 35 | /// Initializes a new instance of the class. 36 | /// 37 | /// The exception message. 38 | /// The inner exception. 39 | public ViewRegistrationException(string message, Exception inner) : base(message, inner) 40 | { 41 | } 42 | 43 | 44 | } 45 | } -------------------------------------------------------------------------------- /tests/Prism.Autofac.Avalonia.Tests/AutofacBootstrapperNullModuleManagerFixture.cs: -------------------------------------------------------------------------------- 1 | using Autofac; 2 | using Avalonia; 3 | using Microsoft.VisualStudio.TestTools.UnitTesting; 4 | using Prism.Logging; 5 | using Prism.Regions; 6 | 7 | namespace Prism.Autofac.Avalonia.Tests 8 | { 9 | [TestClass] 10 | public class AutofacBootstrapperNullModuleManagerFixture 11 | { 12 | [TestMethod] 13 | public void RunShouldNotCallInitializeModulesWhenModuleManagerNotFound() 14 | { 15 | var bootstrapper = new NullModuleManagerBootstrapper(); 16 | 17 | bootstrapper.Run(); 18 | 19 | Assert.IsFalse(bootstrapper.InitializeModulesCalled); 20 | } 21 | 22 | private class NullModuleManagerBootstrapper : AutofacBootstrapper 23 | { 24 | public bool InitializeModulesCalled; 25 | 26 | protected override void ConfigureContainerBuilder(ContainerBuilder builder) 27 | { 28 | builder.RegisterInstance(Logger).As(); 29 | builder.RegisterInstance(ModuleCatalog); 30 | } 31 | 32 | protected override IRegionBehaviorFactory ConfigureDefaultRegionBehaviors() 33 | { 34 | return null; 35 | } 36 | 37 | protected override RegionAdapterMappings ConfigureRegionAdapterMappings() 38 | { 39 | return null; 40 | } 41 | 42 | protected override IAvaloniaObject CreateShell() 43 | { 44 | return null; 45 | } 46 | 47 | protected override void InitializeModules() 48 | { 49 | this.InitializeModulesCalled = true; 50 | } 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /tests/Prism.Avalonia.Tests/Regions/RegionBehaviorFixture.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | using Prism.Avalonia.Tests.Mocks; 4 | using Prism.Regions; 5 | 6 | namespace Prism.Avalonia.Tests.Regions 7 | { 8 | [TestClass] 9 | public class RegionBehaviorFixture 10 | { 11 | [TestMethod] 12 | [ExpectedException(typeof(InvalidOperationException))] 13 | public void CannotChangeRegionAfterAttach() 14 | { 15 | TestableRegionBehavior regionBehavior = new TestableRegionBehavior(); 16 | 17 | regionBehavior.Region = new MockPresentationRegion(); 18 | 19 | regionBehavior.Attach(); 20 | regionBehavior.Region = new MockPresentationRegion(); 21 | } 22 | 23 | [TestMethod] 24 | [ExpectedException(typeof(InvalidOperationException))] 25 | public void ShouldFailWhenAttachedWithoutRegion() 26 | { 27 | TestableRegionBehavior regionBehavior = new TestableRegionBehavior(); 28 | regionBehavior.Attach(); 29 | } 30 | 31 | [TestMethod] 32 | public void ShouldCallOnAttachWhenAttachMethodIsInvoked() 33 | { 34 | TestableRegionBehavior regionBehavior = new TestableRegionBehavior(); 35 | 36 | regionBehavior.Region = new MockPresentationRegion(); 37 | 38 | regionBehavior.Attach(); 39 | 40 | Assert.IsTrue(regionBehavior.onAttachCalled); 41 | } 42 | 43 | private class TestableRegionBehavior : RegionBehavior 44 | { 45 | public bool onAttachCalled; 46 | 47 | protected override void OnAttach() 48 | { 49 | onAttachCalled = true; 50 | } 51 | } 52 | } 53 | 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/Prism.Avalonia/Common/UriParsingHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Prism.Regions; 3 | 4 | namespace Prism.Common 5 | { 6 | /// 7 | /// Helper class for parsing instances. 8 | /// 9 | public static class UriParsingHelper 10 | { 11 | /// 12 | /// Gets the query part of . 13 | /// 14 | /// The Uri. 15 | public static string GetQuery(Uri uri) 16 | { 17 | return EnsureAbsolute(uri).Query; 18 | } 19 | 20 | /// 21 | /// Gets the AbsolutePath part of . 22 | /// 23 | /// The Uri. 24 | public static string GetAbsolutePath(Uri uri) 25 | { 26 | return EnsureAbsolute(uri).AbsolutePath; 27 | } 28 | 29 | /// 30 | /// Parses the query of into a dictionary. 31 | /// 32 | /// The URI. 33 | public static NavigationParameters ParseQuery(Uri uri) 34 | { 35 | var query = GetQuery(uri); 36 | 37 | return new NavigationParameters(query); 38 | } 39 | 40 | private static Uri EnsureAbsolute(Uri uri) 41 | { 42 | if (uri.IsAbsoluteUri) 43 | { 44 | return uri; 45 | } 46 | 47 | if ((uri != null) && !uri.OriginalString.StartsWith("/", StringComparison.Ordinal)) 48 | { 49 | return new Uri("http://localhost/" + uri, UriKind.Absolute); 50 | } 51 | return new Uri("http://localhost" + uri, UriKind.Absolute); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/Prism.Avalonia/Regions/NavigationResult.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Prism.Regions 4 | { 5 | /// 6 | /// Represents the result of navigating to a URI. 7 | /// 8 | public class NavigationResult 9 | { 10 | /// 11 | /// Initializes a new instance of the class. 12 | /// 13 | /// The context. 14 | /// The result. 15 | public NavigationResult(NavigationContext context, bool? result) 16 | { 17 | this.Context = context; 18 | this.Result = result; 19 | } 20 | 21 | /// 22 | /// Initializes a new instance of the class. 23 | /// 24 | /// The context. 25 | /// The error. 26 | public NavigationResult(NavigationContext context, Exception error) 27 | { 28 | this.Context = context; 29 | this.Error = error; 30 | this.Result = false; 31 | } 32 | 33 | /// 34 | /// Gets the result. 35 | /// 36 | /// The result. 37 | public bool? Result { get; private set; } 38 | 39 | /// 40 | /// Gets an exception that occurred while navigating. 41 | /// 42 | /// The exception. 43 | public Exception Error { get; private set; } 44 | 45 | /// 46 | /// Gets the navigation context. 47 | /// 48 | /// The navigation context. 49 | public NavigationContext Context { get; private set; } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /tests/Prism.DryIoc.Avalonia.Tests/DryIocBootstrapperNullModuleManagerFixture.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using Avalonia; 3 | using DryIoc; 4 | using Microsoft.VisualStudio.TestTools.UnitTesting; 5 | using Microsoft.VisualStudio.TestTools.UnitTesting.Logging; 6 | using Prism.Logging; 7 | using Prism.Regions; 8 | 9 | namespace Prism.DryIoc.Avalonia.Tests 10 | { 11 | [TestClass] 12 | public class DryIocBootstrapperNullModuleManagerFixture 13 | { 14 | [TestMethod] 15 | public void RunShouldNotCallInitializeModulesWhenModuleManagerNotFound() 16 | { 17 | var bootstrapper = new NullModuleManagerBootstrapper(); 18 | 19 | bootstrapper.Run(); 20 | 21 | Assert.IsFalse(bootstrapper.InitializeModulesCalled); 22 | } 23 | 24 | private class NullModuleManagerBootstrapper : DryIocBootstrapper 25 | { 26 | public bool InitializeModulesCalled; 27 | 28 | protected override void ConfigureContainer() 29 | { 30 | Container.RegisterInstance(Logger); 31 | Container.RegisterInstance(ModuleCatalog); 32 | } 33 | 34 | protected override IRegionBehaviorFactory ConfigureDefaultRegionBehaviors() 35 | { 36 | return null; 37 | } 38 | 39 | protected override RegionAdapterMappings ConfigureRegionAdapterMappings() 40 | { 41 | return null; 42 | } 43 | 44 | protected override IAvaloniaObject CreateShell() 45 | { 46 | return null; 47 | } 48 | 49 | protected override void InitializeModules() 50 | { 51 | this.InitializeModulesCalled = true; 52 | } 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/Prism.Avalonia/Regions/RegionBehavior.cs: -------------------------------------------------------------------------------- 1 | 2 | 3 | using System; 4 | using Prism.Avalonia.Properties; 5 | using Prism.Properties; 6 | 7 | namespace Prism.Regions 8 | { 9 | /// 10 | /// Provides a base class for region's behaviors. 11 | /// 12 | public abstract class RegionBehavior : IRegionBehavior 13 | { 14 | private IRegion region; 15 | 16 | /// 17 | /// Behavior's attached region. 18 | /// 19 | public IRegion Region 20 | { 21 | get 22 | { 23 | return region; 24 | } 25 | set 26 | { 27 | if (this.IsAttached) 28 | { 29 | throw new InvalidOperationException(Resources.RegionBehaviorRegionCannotBeSetAfterAttach); 30 | } 31 | 32 | this.region = value; 33 | } 34 | } 35 | 36 | /// 37 | /// Returns if the behavior is attached to a region, otherwise. 38 | /// 39 | public bool IsAttached { get; private set; } 40 | 41 | /// 42 | /// Attaches the behavior to the region. 43 | /// 44 | public void Attach() 45 | { 46 | if (this.region == null) 47 | { 48 | throw new InvalidOperationException(Resources.RegionBehaviorAttachCannotBeCallWithNullRegion); 49 | } 50 | 51 | IsAttached = true; 52 | OnAttach(); 53 | } 54 | 55 | /// 56 | /// Override this method to perform the logic after the behavior has been attached. 57 | /// 58 | protected abstract void OnAttach(); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/Prism.Avalonia/Modularity/ModularityException.Desktop.cs: -------------------------------------------------------------------------------- 1 | 2 | 3 | using System; 4 | using System.Runtime.Serialization; 5 | using System.Security.Permissions; 6 | 7 | namespace Prism.Modularity 8 | { 9 | [Serializable] 10 | public partial class ModularityException 11 | { 12 | /// 13 | /// Initializes a new instance with serialized data. 14 | /// 15 | /// The that holds the serialized object data about the exception being thrown. 16 | /// The that contains contextual information about the source or destination. 17 | protected ModularityException(SerializationInfo info, StreamingContext context) 18 | : base(info, context) 19 | { 20 | this.ModuleName = info.GetValue("ModuleName", typeof(string)) as string; 21 | } 22 | 23 | /// 24 | /// Sets the with information about the exception. 25 | /// 26 | /// The that holds the serialized object data about the exception being thrown. 27 | /// The that contains contextual information about the source or destination. 28 | [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.SerializationFormatter)] 29 | public override void GetObjectData(SerializationInfo info, StreamingContext context) 30 | { 31 | base.GetObjectData(info, context); 32 | info.AddValue("ModuleName", this.ModuleName); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /tests/Prism.Avalonia.Tests/Logging/TextLoggerFixture.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Text; 4 | using Microsoft.VisualStudio.TestTools.UnitTesting; 5 | using Prism.Logging; 6 | 7 | namespace Prism.Avalonia.Tests.Logging 8 | { 9 | [TestClass] 10 | public class TextLoggerFixture 11 | { 12 | [TestMethod] 13 | [ExpectedException(typeof(ArgumentNullException))] 14 | public void NullTextWriterThrows() 15 | { 16 | ILoggerFacade logger = new TextLogger(null); 17 | } 18 | 19 | [TestMethod] 20 | public void ShouldWriteToTextWriter() 21 | { 22 | TextWriter writer = new StringWriter(); 23 | ILoggerFacade logger = new TextLogger(writer); 24 | 25 | logger.Log("Test", Category.Debug, Priority.Low); 26 | StringAssert.Contains(writer.ToString(), "Test"); 27 | StringAssert.Contains(writer.ToString(), "DEBUG"); 28 | StringAssert.Contains(writer.ToString(), "Low"); 29 | } 30 | 31 | [TestMethod] 32 | public void ShouldDisposeWriterOnDispose() 33 | { 34 | MockWriter writer = new MockWriter(); 35 | IDisposable logger = new TextLogger(writer); 36 | 37 | Assert.IsFalse(writer.DisposeCalled); 38 | logger.Dispose(); 39 | Assert.IsTrue(writer.DisposeCalled); 40 | } 41 | } 42 | 43 | internal class MockWriter : TextWriter 44 | { 45 | public bool DisposeCalled; 46 | public override Encoding Encoding 47 | { 48 | get { throw new NotImplementedException(); } 49 | } 50 | 51 | protected override void Dispose(bool disposing) 52 | { 53 | DisposeCalled = true; 54 | base.Dispose(disposing); 55 | } 56 | } 57 | } -------------------------------------------------------------------------------- /tests/Prism.Avalonia.Tests/Mocks/MockModuleTypeLoader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Prism.Modularity; 4 | 5 | namespace Prism.Avalonia.Tests.Mocks 6 | { 7 | public class MockModuleTypeLoader : IModuleTypeLoader 8 | { 9 | public List LoadedModules = new List(); 10 | public bool canLoadModuleTypeReturnValue = true; 11 | public Exception LoadCompletedError; 12 | 13 | public bool CanLoadModuleType(ModuleInfo moduleInfo) 14 | { 15 | return canLoadModuleTypeReturnValue; 16 | } 17 | 18 | public void LoadModuleType(ModuleInfo moduleInfo) 19 | { 20 | this.LoadedModules.Add(moduleInfo); 21 | this.RaiseLoadModuleCompleted(new LoadModuleCompletedEventArgs(moduleInfo, this.LoadCompletedError)); 22 | } 23 | 24 | public event EventHandler ModuleDownloadProgressChanged; 25 | 26 | public void RaiseLoadModuleProgressChanged(ModuleDownloadProgressChangedEventArgs e) 27 | { 28 | if (this.ModuleDownloadProgressChanged != null) 29 | { 30 | this.ModuleDownloadProgressChanged(this, e); 31 | } 32 | } 33 | 34 | public event EventHandler LoadModuleCompleted; 35 | 36 | public void RaiseLoadModuleCompleted(ModuleInfo moduleInfo, Exception error) 37 | { 38 | this.RaiseLoadModuleCompleted(new LoadModuleCompletedEventArgs(moduleInfo, error)); 39 | } 40 | 41 | public void RaiseLoadModuleCompleted(LoadModuleCompletedEventArgs e) 42 | { 43 | if (this.LoadModuleCompleted != null) 44 | { 45 | this.LoadModuleCompleted(this, e); 46 | } 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/Prism.Avalonia/Regions/INavigateAsync.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Prism.Regions 4 | { 5 | /// 6 | /// Provides methods to perform navigation. 7 | /// 8 | /// 9 | /// Convenience overloads for the methods in this interface can be found as extension methods on the 10 | /// class. 11 | /// 12 | public interface INavigateAsync 13 | { 14 | /// 15 | /// Initiates navigation to the target specified by the . 16 | /// 17 | /// The navigation target 18 | /// The callback executed when the navigation request is completed. 19 | /// 20 | /// Convenience overloads for this method can be found as extension methods on the 21 | /// class. 22 | /// 23 | void RequestNavigate(Uri target, Action navigationCallback); 24 | 25 | /// 26 | /// Initiates navigation to the target specified by the . 27 | /// 28 | /// The navigation target 29 | /// The callback executed when the navigation request is completed. 30 | /// The navigation parameters specific to the navigation request. 31 | /// 32 | /// Convenience overloads for this method can be found as extension methods on the 33 | /// class. 34 | /// 35 | void RequestNavigate(Uri target, Action navigationCallback, NavigationParameters navigationParameters); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Prism.Avalonia/Modularity/LoadModuleCompletedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Prism.Modularity 4 | { 5 | /// 6 | /// Provides completion information after a module is loaded, or fails to load. 7 | /// 8 | public class LoadModuleCompletedEventArgs : EventArgs 9 | { 10 | /// 11 | /// Initializes a new instance of the class. 12 | /// 13 | /// The module info. 14 | /// Any error that occurred during the call. 15 | public LoadModuleCompletedEventArgs(ModuleInfo moduleInfo, Exception error) 16 | { 17 | if (moduleInfo == null) 18 | { 19 | throw new ArgumentNullException(nameof(moduleInfo)); 20 | } 21 | 22 | this.ModuleInfo = moduleInfo; 23 | this.Error = error; 24 | } 25 | 26 | /// 27 | /// Gets the module info. 28 | /// 29 | /// The module info. 30 | public ModuleInfo ModuleInfo { get; private set; } 31 | 32 | /// 33 | /// Gets any error that occurred 34 | /// 35 | /// The exception if an error occurred; otherwise null. 36 | public Exception Error { get; private set; } 37 | 38 | /// 39 | /// Gets or sets a value indicating whether the error has been handled by the event subscriber. 40 | /// 41 | /// trueif the error is handled; otherwise, false. 42 | /// 43 | /// If there is an error on this event and no event subscriber sets this to true, an exception will be thrown by the event publisher. 44 | /// 45 | public bool IsErrorHandled { get; set; } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /tests/Prism.Avalonia.Tests/Mocks/MockAsyncModuleTypeLoader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | using Prism.Modularity; 4 | 5 | namespace Prism.Avalonia.Tests.Mocks 6 | { 7 | public class MockAsyncModuleTypeLoader : IModuleTypeLoader 8 | { 9 | private ManualResetEvent callbackEvent; 10 | 11 | public MockAsyncModuleTypeLoader(ManualResetEvent callbackEvent) 12 | { 13 | this.callbackEvent = callbackEvent; 14 | } 15 | 16 | public int SleepTimeOut { get; set; } 17 | 18 | public Exception CallbackArgumentError { get; set; } 19 | 20 | public bool CanLoadModuleType(ModuleInfo moduleInfo) 21 | { 22 | return true; 23 | } 24 | 25 | public void LoadModuleType(ModuleInfo moduleInfo) 26 | { 27 | Thread retrieverThread = new Thread(() => 28 | { 29 | Thread.Sleep(SleepTimeOut); 30 | 31 | this.RaiseLoadModuleCompleted(new LoadModuleCompletedEventArgs(moduleInfo, CallbackArgumentError)); 32 | callbackEvent.Set(); 33 | }); 34 | retrieverThread.Start(); 35 | } 36 | 37 | 38 | public event EventHandler ModuleDownloadProgressChanged; 39 | 40 | private void RaiseLoadModuleProgressChanged(ModuleDownloadProgressChangedEventArgs e) 41 | { 42 | if (this.ModuleDownloadProgressChanged != null) 43 | { 44 | this.ModuleDownloadProgressChanged(this, e); 45 | } 46 | } 47 | 48 | public event EventHandler LoadModuleCompleted; 49 | 50 | private void RaiseLoadModuleCompleted(LoadModuleCompletedEventArgs e) 51 | { 52 | if (this.LoadModuleCompleted != null) 53 | { 54 | this.LoadModuleCompleted(this, e); 55 | } 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /samples/ModulesSample/MainWindow.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.ObjectModel; 2 | using System.Globalization; 3 | using Avalonia; 4 | using Avalonia.Controls; 5 | using Avalonia.Controls.Primitives; 6 | using Avalonia.Markup.Xaml; 7 | using Avalonia.Threading; 8 | using Prism.Avalonia.Infrastructure.Events; 9 | using Prism.Events; 10 | using Prism.Logging; 11 | 12 | namespace ModulesSample 13 | { 14 | public class MainWindow : Window 15 | { 16 | private readonly CallbackLogger logger; 17 | private readonly IEventAggregator eventAggregator; 18 | 19 | private TextBox logTextBox; 20 | private ListBox itemsControl; 21 | 22 | public MainWindow(CallbackLogger logger, IEventAggregator eventAggregator) 23 | { 24 | this.InitializeComponent(); 25 | this.AttachDevTools(); 26 | 27 | this.logTextBox = this.FindControl("LogTextBox"); 28 | this.itemsControl = this.FindControl("ItemsControl1"); 29 | 30 | this.logger = logger; 31 | this.logger.Callback = this.Log; 32 | this.logger.ReplaySavedLogs(); 33 | 34 | this.eventAggregator = eventAggregator; 35 | this.eventAggregator.GetEvent().Subscribe(() => 36 | { 37 | Dispatcher.UIThread.InvokeAsync(() => 38 | { 39 | logTextBox.Text += "EventAggregator DummyEvent triggered \r\n"; 40 | }); 41 | }); 42 | 43 | this.DataContext = this; 44 | } 45 | 46 | private void InitializeComponent() 47 | { 48 | AvaloniaXamlLoader.Load(this); 49 | } 50 | 51 | private void Log(string message, Category category, Priority priority) 52 | { 53 | this.logTextBox.Text += string.Format(CultureInfo.CurrentUICulture, "[{0}][{1}] {2} \r\n", category, 54 | priority, message); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/Prism.Avalonia/Regions/IRegionBehaviorFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Prism.Regions 5 | { 6 | /// 7 | /// Interface for RegionBehaviorFactories. This factory allows the registration of the default set of RegionBehaviors, that will 8 | /// be added to the s of all s, unless overridden on a 'per-region' basis. 9 | /// 10 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix", Justification = "It is more of a factory than a collection")] 11 | public interface IRegionBehaviorFactory : IEnumerable 12 | { 13 | /// 14 | /// Adds a particular type of RegionBehavior if it was not already registered. the string is used to check if the behavior is already present 15 | /// 16 | /// The behavior key that's used to find if a certain behavior is already added. 17 | /// Type of the behavior to add. . 18 | void AddIfMissing(string behaviorKey, Type behaviorType); 19 | 20 | /// 21 | /// Determines whether a behavior with the specified key already exists 22 | /// 23 | /// The behavior key. 24 | /// 25 | /// if a behavior with the specified key is present; otherwise, . 26 | /// 27 | bool ContainsKey(string behaviorKey); 28 | 29 | /// 30 | /// Creates an instance of the Behaviortype that's registered using the specified key. 31 | /// 32 | /// The key that's used to register a behavior type. 33 | /// The created behavior. 34 | IRegionBehavior CreateFromKey(string key); 35 | } 36 | } -------------------------------------------------------------------------------- /src/Prism.Avalonia/Regions/DefaultRegionManagerAccessor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Avalonia; 3 | 4 | namespace Prism.Regions 5 | { 6 | internal class DefaultRegionManagerAccessor : IRegionManagerAccessor 7 | { 8 | /// 9 | /// Notification used by attached behaviors to update the region managers appropriatelly if needed to. 10 | /// 11 | /// This event uses weak references to the event handler to prevent this static event of keeping the 12 | /// target element longer than expected. 13 | public event EventHandler UpdatingRegions 14 | { 15 | add { RegionManager.UpdatingRegions += value; } 16 | remove { RegionManager.UpdatingRegions -= value; } 17 | } 18 | 19 | /// 20 | /// Gets the value for the RegionName attached property. 21 | /// 22 | /// The object to adapt. This is typically a container (i.e a control). 23 | /// The name of the region that should be created when 24 | /// the RegionManager is also set in this element. 25 | public string GetRegionName(AvaloniaObject element) 26 | { 27 | if (element == null) 28 | throw new ArgumentNullException(nameof(element)); 29 | 30 | return element.GetValue(RegionManager.RegionNameProperty) as string; 31 | } 32 | 33 | /// 34 | /// Gets the value of the RegionName attached property. 35 | /// 36 | /// The target element. 37 | /// The attached to the element. 38 | public IRegionManager GetRegionManager(AvaloniaObject element) 39 | { 40 | if (element == null) 41 | throw new ArgumentNullException(nameof(element)); 42 | 43 | return element.GetValue(RegionManager.RegionManagerProperty) as IRegionManager; 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /src/Prism.Avalonia/Extensions/ServiceLocatorExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CommonServiceLocator 4 | { 5 | /// 6 | /// Defines extension methods for the class. 7 | /// 8 | public static class ServiceLocatorExtensions 9 | { 10 | /// 11 | /// Attempts to resolve specified type from the underlying . 12 | /// 13 | /// 14 | /// This will return null on any . 15 | /// Locator to use in resolving. 16 | /// Type to resolve. 17 | /// T or null 18 | /// Thrown when is . 19 | public static object TryResolve(this IServiceLocator locator, Type type) 20 | { 21 | if (locator == null) throw new ArgumentNullException(nameof(locator)); 22 | 23 | try 24 | { 25 | return locator.GetInstance(type); 26 | } 27 | catch (ActivationException) 28 | { 29 | return null; 30 | } 31 | } 32 | 33 | /// 34 | /// Attempts to resolve specified type from the underlying . 35 | /// 36 | /// 37 | /// This will return null on any . 38 | /// Type to resolve. 39 | /// Locator to use in resolving. 40 | /// T or null 41 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter")] 42 | public static T TryResolve(this IServiceLocator locator) where T : class 43 | { 44 | return locator.TryResolve(typeof(T)) as T; 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Prism.Avalonia/Regions/IRegionViewRegistry.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Prism.Regions 5 | { 6 | /// 7 | /// Defines the interface for the registry of region's content. 8 | /// 9 | public interface IRegionViewRegistry 10 | { 11 | /// 12 | /// Event triggered when a content is registered to a region name. 13 | /// 14 | /// 15 | /// This event uses weak references to the event handler to prevent this service (typically a singleton) of keeping the 16 | /// target element longer than expected. 17 | /// 18 | event EventHandler ContentRegistered; 19 | 20 | /// 21 | /// Returns the contents associated with a region name. 22 | /// 23 | /// Region name for which contents are requested. 24 | /// Collection of contents associated with the . 25 | IEnumerable GetContents(string regionName); 26 | 27 | /// 28 | /// Registers a content type with a region name. 29 | /// 30 | /// Region name to which the will be registered. 31 | /// Content type to be registered for the . 32 | void RegisterViewWithRegion(string regionName, Type viewType); 33 | 34 | /// 35 | /// Registers a delegate that can be used to retrieve the content associated with a region name. 36 | /// 37 | /// Region name to which the will be registered. 38 | /// Delegate used to retrieve the content associated with the . 39 | void RegisterViewWithRegion(string regionName, Func getContentDelegate); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Prism.DryIoc.Avalonia/DryIocServiceLocatorAdapter.cs: -------------------------------------------------------------------------------- 1 | using DryIoc; 2 | using CommonServiceLocator; 3 | using System; 4 | using System.Collections.Generic; 5 | 6 | namespace Prism.DryIoc 7 | { 8 | public class DryIocServiceLocatorAdapter : ServiceLocatorImplBase 9 | { 10 | /// Exposes underlying Container for direct operation. 11 | public readonly IContainer _container; 12 | 13 | /// Creates new locator as adapter for provided container. 14 | /// Container to use/adapt. 15 | public DryIocServiceLocatorAdapter(IContainer container) 16 | { 17 | if (container == null) throw new ArgumentNullException("container"); 18 | _container = container; 19 | } 20 | 21 | /// Resolves service from container. Throws if unable to resolve. 22 | /// Service type to resolve. 23 | /// (optional) Service key to resolve. 24 | /// Resolved service object. 25 | protected override object DoGetInstance(Type serviceType, string key) 26 | { 27 | if (serviceType == null) throw new ArgumentNullException("serviceType"); 28 | return _container.Resolve(serviceType, key); 29 | } 30 | 31 | /// Returns enumerable which when enumerated! resolves all default and named 32 | /// implementations/registrations of requested service type. 33 | /// If no services resolved when enumerable accessed, no exception is thrown - enumerable is empty. 34 | /// Service type to resolve. 35 | /// Returns enumerable which will return resolved service objects. 36 | protected override IEnumerable DoGetAllInstances(Type serviceType) 37 | { 38 | if (serviceType == null) throw new ArgumentNullException("serviceType"); 39 | return _container.ResolveMany(serviceType); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /tests/Prism.Avalonia.Tests/Regions/NavigationContextFixture.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using Microsoft.VisualStudio.TestTools.UnitTesting; 4 | using Moq; 5 | using Prism.Regions; 6 | 7 | namespace Prism.Avalonia.Tests.Regions 8 | { 9 | [TestClass] 10 | public class NavigationContextFixture 11 | { 12 | [TestMethod] 13 | public void WhenCreatingANewContextForAUriWithAQuery_ThenNewContextInitializesPropertiesAndExtractsTheQuery() 14 | { 15 | var uri = new Uri("test?name=value", UriKind.Relative); 16 | 17 | var navigationJournalMock = new Mock(); 18 | var navigationServiceMock = new Mock(); 19 | 20 | IRegion region = new Region(); 21 | navigationServiceMock.SetupGet(n => n.Region).Returns(region); 22 | navigationServiceMock.SetupGet(x => x.Journal).Returns(navigationJournalMock.Object); 23 | 24 | var context = new NavigationContext(navigationServiceMock.Object, uri); 25 | 26 | Assert.AreSame(navigationServiceMock.Object, context.NavigationService); 27 | Assert.AreEqual(uri, context.Uri); 28 | Assert.AreEqual(1, context.Parameters.Count()); 29 | Assert.AreEqual("value", context.Parameters["name"]); 30 | } 31 | 32 | [TestMethod] 33 | public void WhenCreatingANewContextForAUriWithNoQuery_ThenNewContextInitializesPropertiesGetsEmptyQuery() 34 | { 35 | var uri = new Uri("test", UriKind.Relative); 36 | 37 | var navigationJournalMock = new Mock(); 38 | 39 | var navigationServiceMock = new Mock(); 40 | navigationServiceMock.SetupGet(x => x.Journal).Returns(navigationJournalMock.Object); 41 | 42 | var context = new NavigationContext(navigationServiceMock.Object, uri); 43 | 44 | Assert.AreSame(navigationServiceMock.Object, context.NavigationService); 45 | Assert.AreEqual(uri, context.Uri); 46 | Assert.AreEqual(0, context.Parameters.Count()); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /samples/ModulesSample/CallbackLogger.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Prism.Logging; 4 | 5 | namespace ModulesSample 6 | { 7 | /// 8 | /// A logger that holds on to log entries until a callback delegate is set, then plays back log 9 | /// entries and sends new log entries 10 | /// 11 | public class CallbackLogger : ILoggerFacade 12 | { 13 | #region ILoggerFacade members 14 | 15 | private readonly Queue> savedLogs = 16 | new Queue>(); 17 | 18 | /// 19 | /// Gets or sets the callback to receive logs 20 | /// 21 | /// An Action<string, Category> callback 22 | public Action Callback { private get; set; } 23 | 24 | /// 25 | /// Write a new log entry with the specified category and priority 26 | /// 27 | /// Message body to log 28 | /// Category of the log message 29 | /// The priority of the entry 30 | public void Log(string message, Category category, Priority priority) 31 | { 32 | if (this.Callback != null) 33 | { 34 | this.Callback(message, category, priority); 35 | } 36 | else 37 | { 38 | savedLogs.Enqueue(new Tuple(message, category, priority)); 39 | } 40 | } 41 | 42 | /// 43 | /// Replays the saved logs if the Callback has been set 44 | /// 45 | public void ReplaySavedLogs() 46 | { 47 | if (this.Callback != null) 48 | { 49 | while (this.savedLogs.Count > 0) 50 | { 51 | var log = this.savedLogs.Dequeue(); 52 | this.Callback(log.Item1, log.Item2, log.Item3); 53 | } 54 | } 55 | } 56 | 57 | #endregion 58 | } 59 | } -------------------------------------------------------------------------------- /tests/Prism.Autofac.Avalonia.Tests/AutofacBootstrapperNullContainerFixture.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Autofac; 3 | using Avalonia; 4 | using Microsoft.VisualStudio.TestTools.UnitTesting; 5 | using Prism.IocContainer.Avalonia.Tests.Support; 6 | 7 | namespace Prism.Autofac.Avalonia.Tests 8 | { 9 | [TestClass] 10 | public class AutofacBootstrapperNullContainerFixture : BootstrapperFixtureBase 11 | { 12 | [TestMethod] 13 | public void RunThrowsWhenNullContainerBuilderCreated() 14 | { 15 | var bootstrapper = new NullContainerBuilderBootstrapper(); 16 | 17 | AssertExceptionThrownOnRun(bootstrapper, typeof(InvalidOperationException), "ContainerBuilder"); 18 | } 19 | 20 | [TestMethod] 21 | public void RunThrowsWhenNullContainerCreated() 22 | { 23 | var bootstrapper = new NullContainerBootstrapper(); 24 | 25 | AssertExceptionThrownOnRun(bootstrapper, typeof(InvalidOperationException), "IContainer"); 26 | } 27 | 28 | private class NullContainerBuilderBootstrapper : AutofacBootstrapper 29 | { 30 | protected override ContainerBuilder CreateContainerBuilder() 31 | { 32 | return null; 33 | } 34 | 35 | protected override IAvaloniaObject CreateShell() 36 | { 37 | throw new NotImplementedException(); 38 | } 39 | 40 | protected override void InitializeShell() 41 | { 42 | throw new NotImplementedException(); 43 | } 44 | } 45 | 46 | private class NullContainerBootstrapper : AutofacBootstrapper 47 | { 48 | protected override IContainer CreateContainer(ContainerBuilder builder) 49 | { 50 | return null; 51 | } 52 | 53 | protected override IAvaloniaObject CreateShell() 54 | { 55 | throw new NotImplementedException(); 56 | } 57 | 58 | protected override void InitializeShell() 59 | { 60 | throw new NotImplementedException(); 61 | } 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/Prism.Avalonia/Mvvm/ViewModelLocator.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using System.Threading; 3 | using System; 4 | using Avalonia; 5 | using Avalonia.Controls; 6 | 7 | #if NETFX_CORE 8 | using Windows.UI.Xaml; 9 | #endif 10 | namespace Prism.Mvvm 11 | { 12 | /// 13 | /// This class defines the attached property and related change handler that calls the ViewModelLocator in Prism.Mvvm. 14 | /// 15 | public static class ViewModelLocator 16 | { 17 | /// 18 | /// The AutoWireViewModel attached property. 19 | /// 20 | public static AvaloniaProperty AutoWireViewModelProperty = 21 | AvaloniaProperty.RegisterAttached(name: "AutoWireViewModel", ownerType: typeof(ViewModelLocator), defaultValue: false); 22 | public static bool GetAutoWireViewModel(AvaloniaObject obj) 23 | { 24 | return (bool)obj.GetValue(AutoWireViewModelProperty); 25 | } 26 | 27 | public static void SetAutoWireViewModel(AvaloniaObject obj, bool value) 28 | { 29 | obj.SetValue(AutoWireViewModelProperty, value); 30 | } 31 | 32 | private static void AutoWireViewModelChanged(AvaloniaObject d, 33 | AvaloniaPropertyChangedEventArgs e) 34 | { 35 | if ((bool) e.NewValue) 36 | { 37 | ViewModelLocationProvider.AutoWireViewModelChanged(d, Bind); 38 | } 39 | } 40 | 41 | /// 42 | /// Sets the DataContext of a View 43 | /// 44 | /// The View to set the DataContext on 45 | /// The object to use as the DataContext for the View 46 | static void Bind(object view, object viewModel) 47 | { 48 | Control element = view as Control; 49 | if (element != null) 50 | element.DataContext = viewModel; 51 | } 52 | 53 | static ViewModelLocator() 54 | { 55 | // Bind AutoWireViewModelProperty.Changed to its callback 56 | AutoWireViewModelProperty.Changed.Subscribe(args => AutoWireViewModelChanged(args?.Sender, args)); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /samples/ModulesSample/Module System Logic/ModuleTracker.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using Prism.Avalonia.Infrastructure; 4 | using Prism.Logging; 5 | 6 | namespace ModulesSample.Module_System_Logic 7 | { 8 | class ModuleTracker : IModuleTracker 9 | { 10 | private ILoggerFacade logger; 11 | 12 | public ModuleTracker(ILoggerFacade logger) 13 | { 14 | if (logger == null) 15 | { 16 | throw new ArgumentNullException(nameof(logger)); 17 | } 18 | this.logger = logger; 19 | } 20 | 21 | public ModuleTrackingState ModuleCodeEditorTrackingState { get; } 22 | 23 | public void RecordModuleLoaded(string moduleName) 24 | { 25 | this.logger.Log(string.Format(CultureInfo.CurrentCulture, "'{0}' module loaded.", moduleName), 26 | Category.Debug, Priority.Low); 27 | } 28 | 29 | public void RecordModuleConstructed(string moduleName) 30 | { 31 | ModuleTrackingState moduleTrackingState = this.GetModuleTrackingState(moduleName); 32 | if (moduleTrackingState != null) 33 | { 34 | moduleTrackingState.ModuleInitializationStatus = ModuleInitializationStatus.Constructed; 35 | } 36 | 37 | this.logger.Log(string.Format(CultureInfo.CurrentCulture, "'{0}' module constructed.", moduleName), 38 | Category.Debug, Priority.Low); 39 | } 40 | 41 | public void RecordModuleInitialized(string moduleName) 42 | { 43 | ModuleTrackingState moduleTrackingState = this.GetModuleTrackingState(moduleName); 44 | if (moduleTrackingState != null) 45 | { 46 | moduleTrackingState.ModuleInitializationStatus = ModuleInitializationStatus.Initialized; 47 | } 48 | 49 | 50 | this.logger.Log(string.Format(CultureInfo.CurrentCulture, "'{0}' module initialized.", moduleName), 51 | Category.Debug, Priority.Low); 52 | } 53 | 54 | private ModuleTrackingState GetModuleTrackingState(string moduleName) 55 | { 56 | switch (moduleName) 57 | { 58 | default: 59 | return null; 60 | } 61 | } 62 | } 63 | } -------------------------------------------------------------------------------- /src/Prism.Avalonia/Modularity/CyclicDependencyFoundException.cs: -------------------------------------------------------------------------------- 1 | 2 | 3 | using System; 4 | 5 | namespace Prism.Modularity 6 | { 7 | /// 8 | /// Represents the exception that is thrown when there is a circular dependency 9 | /// between modules during the module loading process. 10 | /// 11 | public partial class CyclicDependencyFoundException : ModularityException 12 | { 13 | /// 14 | /// Initializes a new instance of the class. 15 | /// 16 | public CyclicDependencyFoundException() : base() { } 17 | 18 | /// 19 | /// Initializes a new instance of the class 20 | /// with the specified error message. 21 | /// 22 | /// The message that describes the error. 23 | public CyclicDependencyFoundException(string message) : base(message) { } 24 | 25 | /// 26 | /// Initializes a new instance of the class 27 | /// with the specified error message and inner exception. 28 | /// 29 | /// The error message that explains the reason for the exception. 30 | /// The exception that is the cause of the current exception. 31 | public CyclicDependencyFoundException(string message, Exception innerException) : base(message, innerException) { } 32 | 33 | /// 34 | /// Initializes the exception with a particular module, error message and inner exception that happened. 35 | /// 36 | /// The name of the module. 37 | /// The error message that explains the reason for the exception. 38 | /// The exception that is the cause of the current exception, 39 | /// or a reference if no inner exception is specified. 40 | public CyclicDependencyFoundException(string moduleName, string message, Exception innerException) 41 | : base(moduleName, message, innerException) 42 | { 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /src/Prism.Avalonia/Modularity/ModuleDownloadProgressChangedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | 4 | namespace Prism.Modularity 5 | { 6 | /// 7 | /// Provides progress information as a module downloads. 8 | /// 9 | public class ModuleDownloadProgressChangedEventArgs : ProgressChangedEventArgs 10 | { 11 | /// 12 | /// Initializes a new instance of the class. 13 | /// 14 | /// The module info. 15 | /// The bytes received. 16 | /// The total bytes to receive. 17 | public ModuleDownloadProgressChangedEventArgs(ModuleInfo moduleInfo, long bytesReceived, long totalBytesToReceive) 18 | : base(CalculateProgressPercentage(bytesReceived, totalBytesToReceive), null) 19 | { 20 | if (moduleInfo == null) 21 | throw new ArgumentNullException(nameof(moduleInfo)); 22 | 23 | this.ModuleInfo = moduleInfo; 24 | this.BytesReceived = bytesReceived; 25 | this.TotalBytesToReceive = totalBytesToReceive; 26 | } 27 | 28 | /// 29 | /// Getsthe module info. 30 | /// 31 | /// The module info. 32 | public ModuleInfo ModuleInfo { get; private set; } 33 | 34 | /// 35 | /// Gets the bytes received. 36 | /// 37 | /// The bytes received. 38 | public long BytesReceived { get; private set; } 39 | 40 | /// 41 | /// Gets the total bytes to receive. 42 | /// 43 | /// The total bytes to receive. 44 | public long TotalBytesToReceive { get; private set; } 45 | 46 | 47 | private static int CalculateProgressPercentage(long bytesReceived, long totalBytesToReceive) 48 | { 49 | if ((bytesReceived == 0L) || (totalBytesToReceive == 0L) || (totalBytesToReceive == -1L)) 50 | { 51 | return 0; 52 | } 53 | 54 | return (int)((bytesReceived * 100L) / totalBytesToReceive); 55 | 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/Prism.Avalonia/Regions/RegionContext.cs: -------------------------------------------------------------------------------- 1 | 2 | 3 | using Prism.Common; 4 | using System; 5 | using System.Windows; 6 | using Avalonia; 7 | using Avalonia.Controls; 8 | 9 | namespace Prism.Regions 10 | { 11 | /// 12 | /// Class that holds methods to Set and Get the RegionContext from a DependencyObject. 13 | /// 14 | /// RegionContext allows sharing of contextual information between the view that's hosting a 15 | /// and any views that are inside the Region. 16 | /// 17 | public static class RegionContext 18 | { 19 | private static readonly AvaloniaProperty ObservableRegionContextProperty = 20 | AvaloniaProperty.RegisterAttached>("ObservableRegionContext", typeof(RegionContext)); 21 | 22 | /// 23 | /// Returns an wrapper around the RegionContext value. The RegionContext 24 | /// will be set on any views (dependency objects) that are inside the collection by 25 | /// the Behavior. 26 | /// The RegionContext will also be set to the control that hosts the Region, by the Behavior. 27 | /// 28 | /// If the wrapper does not already exist, an empty one will be created. This way, an observer can 29 | /// notify when the value is set for the first time. 30 | /// 31 | /// Any view that hold the RegionContext value. 32 | /// Wrapper around the Regioncontext value. 33 | public static ObservableObject GetObservableContext(Visual view) 34 | { 35 | if (view == null) 36 | throw new ArgumentNullException(nameof(view)); 37 | 38 | ObservableObject context = view.GetValue(ObservableRegionContextProperty) as ObservableObject; 39 | 40 | if (context == null) 41 | { 42 | context = new ObservableObject(); 43 | view.SetValue(ObservableRegionContextProperty, context); 44 | } 45 | 46 | return context; 47 | } 48 | 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/Prism.Autofac.Avalonia/AutofacServiceLocatorAdapter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using Autofac; 6 | using CommonServiceLocator; 7 | 8 | namespace Prism.Autofac 9 | { 10 | /// 11 | /// Defines a adapter for the interface to be used by the Prism Library. 12 | /// 13 | public class AutofacServiceLocatorAdapter : ServiceLocatorImplBase 14 | { 15 | private readonly IContainer _container; 16 | 17 | /// 18 | /// Initializes a new instance of . 19 | /// 20 | /// The that will be used 21 | /// by the and methods. 22 | public AutofacServiceLocatorAdapter(IContainer container) 23 | { 24 | if (container == null) 25 | throw new ArgumentNullException(nameof(container)); 26 | _container = container; 27 | } 28 | 29 | /// 30 | /// Resolves the instance of the requested service. 31 | /// 32 | /// Type of instance requested. 33 | /// Name of registered service you want. May be null. 34 | /// The requested service instance. 35 | protected override object DoGetInstance(Type serviceType, string key) 36 | { 37 | return key != null ? 38 | _container.ResolveNamed(key, serviceType) : 39 | _container.Resolve(serviceType); 40 | } 41 | 42 | /// 43 | /// Resolves all the instances of the requested service. 44 | /// 45 | /// Type of service requested. 46 | /// Sequence of service instance objects. 47 | protected override IEnumerable DoGetAllInstances(Type serviceType) 48 | { 49 | var enumerableType = typeof(IEnumerable<>).MakeGenericType(serviceType); 50 | 51 | object instance = _container.Resolve(enumerableType); 52 | return ((IEnumerable)instance).Cast(); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /tests/Prism.Avalonia.Tests/Regions/RegionBehaviorFactoryFixture.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using Microsoft.VisualStudio.TestTools.UnitTesting; 4 | using Prism.Avalonia.Tests.Mocks; 5 | using Prism.Regions; 6 | 7 | namespace Prism.Avalonia.Tests.Regions 8 | { 9 | [TestClass] 10 | public class RegionBehaviorFactoryFixture 11 | { 12 | [TestMethod] 13 | public void CanRegisterType() 14 | { 15 | RegionBehaviorFactory factory = new RegionBehaviorFactory(null); 16 | 17 | factory.AddIfMissing("key1", typeof(MockRegionBehavior)); 18 | factory.AddIfMissing("key2", typeof(MockRegionBehavior)); 19 | 20 | Assert.AreEqual(2, factory.Count()); 21 | Assert.IsTrue(factory.ContainsKey("key1")); 22 | 23 | } 24 | 25 | [TestMethod] 26 | public void WillNotAddTypesWithDuplicateKeys() 27 | { 28 | RegionBehaviorFactory factory = new RegionBehaviorFactory(null); 29 | 30 | factory.AddIfMissing("key1", typeof(MockRegionBehavior)); 31 | factory.AddIfMissing("key1", typeof(MockRegionBehavior)); 32 | 33 | Assert.AreEqual(1, factory.Count()); 34 | } 35 | 36 | [TestMethod] 37 | [ExpectedException(typeof(ArgumentException))] 38 | public void AddTypeThatDoesNotInheritFromIRegionBehaviorThrows() 39 | { 40 | RegionBehaviorFactory factory = new RegionBehaviorFactory(null); 41 | 42 | factory.AddIfMissing("key1", typeof(object)); 43 | } 44 | 45 | [TestMethod] 46 | public void CanCreateRegisteredType() 47 | { 48 | var expectedBehavior = new MockRegionBehavior(); 49 | 50 | RegionBehaviorFactory factory = new RegionBehaviorFactory(new MockServiceLocator() { GetInstance = (t) => expectedBehavior }); 51 | 52 | factory.AddIfMissing("key1", typeof(MockRegionBehavior)); 53 | var behavior = factory.CreateFromKey("key1"); 54 | 55 | Assert.AreSame(expectedBehavior, behavior); 56 | } 57 | 58 | [TestMethod] 59 | [ExpectedException(typeof(ArgumentException))] 60 | public void CreateWithUnknownKeyThrows() 61 | { 62 | RegionBehaviorFactory factory = new RegionBehaviorFactory(null); 63 | 64 | factory.CreateFromKey("Key1"); 65 | } 66 | 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/Prism.Avalonia/Regions/RegionNavigationFailedEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Prism.Regions 4 | { 5 | /// 6 | /// EventArgs used with the NavigationFailed event. 7 | /// 8 | public class RegionNavigationFailedEventArgs : EventArgs 9 | { 10 | /// 11 | /// Initializes a new instance of the class. 12 | /// 13 | /// The navigation context. 14 | public RegionNavigationFailedEventArgs(NavigationContext navigationContext) 15 | { 16 | if (navigationContext == null) 17 | throw new ArgumentNullException(nameof(navigationContext)); 18 | 19 | this.NavigationContext = navigationContext; 20 | } 21 | 22 | /// 23 | /// Initializes a new instance of the class. 24 | /// 25 | /// The navigation context. 26 | /// The error. 27 | public RegionNavigationFailedEventArgs(NavigationContext navigationContext, Exception error) 28 | : this(navigationContext) 29 | { 30 | this.Error = error; 31 | } 32 | 33 | /// 34 | /// Gets the navigation context. 35 | /// 36 | /// The navigation context. 37 | public NavigationContext NavigationContext { get; private set; } 38 | 39 | /// 40 | /// Gets the error. 41 | /// 42 | /// The , or if the failure was not caused by an exception. 43 | public Exception Error { get; private set; } 44 | 45 | /// 46 | /// Gets the navigation URI 47 | /// 48 | /// The URI. 49 | /// 50 | /// This is a convenience accessor around NavigationContext.Uri. 51 | /// 52 | public Uri Uri 53 | { 54 | get 55 | { 56 | if (this.NavigationContext != null) 57 | { 58 | return this.NavigationContext.Uri; 59 | } 60 | 61 | return null; 62 | } 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/Prism.Avalonia/Modularity/IModuleCatalog.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Prism.Modularity 4 | { 5 | /// 6 | /// This is the expected catalog definition for the ModuleManager. 7 | /// The ModuleCatalog holds information about the modules that can be used by the 8 | /// application. Each module is described in a ModuleInfo class, that records the 9 | /// name, type and location of the module. 10 | /// 11 | public interface IModuleCatalog 12 | { 13 | /// 14 | /// Gets all the classes that are in the . 15 | /// 16 | IEnumerable Modules { get; } 17 | 18 | /// 19 | /// Return the list of s that depends on. 20 | /// 21 | /// The to get the 22 | /// An enumeration of that depends on. 23 | IEnumerable GetDependentModules(ModuleInfo moduleInfo); 24 | 25 | /// 26 | /// Returns the collection of s that contain both the s in 27 | /// , but also all the modules they depend on. 28 | /// 29 | /// The modules to get the dependencies for. 30 | /// 31 | /// A collection of that contains both all s in 32 | /// and also all the they depend on. 33 | /// 34 | IEnumerable CompleteListWithDependencies(IEnumerable modules); 35 | 36 | /// 37 | /// Initializes the catalog, which may load and validate the modules. 38 | /// 39 | void Initialize(); 40 | 41 | /// 42 | /// Adds a to the . 43 | /// 44 | /// The to add. 45 | /// The for easily adding multiple modules. 46 | void AddModule(ModuleInfo moduleInfo); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Prism.Avalonia/Modularity/ModuleTypeLoaderNotFoundException.cs: -------------------------------------------------------------------------------- 1 | 2 | 3 | using System; 4 | 5 | namespace Prism.Modularity 6 | { 7 | /// 8 | /// Exception that's thrown when there is no registered in 9 | /// that can handle this particular type of module. 10 | /// 11 | public partial class ModuleTypeLoaderNotFoundException : ModularityException 12 | { 13 | /// 14 | /// Initializes a new instance of the class. 15 | /// 16 | public ModuleTypeLoaderNotFoundException() 17 | { 18 | } 19 | 20 | /// 21 | /// Initializes a new instance of the class with a specified error message. 22 | /// 23 | /// 24 | /// The message that describes the error. 25 | /// 26 | public ModuleTypeLoaderNotFoundException(string message) 27 | : base(message) 28 | { 29 | } 30 | 31 | /// 32 | /// Initializes a new instance of the class with a specified error message. 33 | /// 34 | /// 35 | /// The message that describes the error. 36 | /// 37 | /// The inner exception 38 | public ModuleTypeLoaderNotFoundException(string message, Exception innerException) 39 | : base(message, innerException) 40 | { 41 | } 42 | 43 | /// 44 | /// Initializes the exception with a particular module, error message and inner exception that happened. 45 | /// 46 | /// The name of the module. 47 | /// The error message that explains the reason for the exception. 48 | /// The exception that is the cause of the current exception, 49 | /// or a reference if no inner exception is specified. 50 | public ModuleTypeLoaderNotFoundException(string moduleName, string message, Exception innerException) 51 | : base(moduleName, message, innerException) 52 | { 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/Prism.Autofac.Avalonia/AutofacExtensions.cs: -------------------------------------------------------------------------------- 1 | using Autofac; 2 | using Prism.Mvvm; 3 | using System; 4 | 5 | namespace Prism.Autofac 6 | { 7 | public static class AutofacExtensions 8 | { 9 | /// 10 | /// Registers an object for navigation. 11 | /// 12 | /// The Type of the object to register 13 | /// used to build 14 | /// The unique name to register with the object 15 | public static void RegisterTypeForNavigation(this ContainerBuilder builder, string name = null) 16 | { 17 | Type type = typeof(T); 18 | string viewName = string.IsNullOrWhiteSpace(name) ? type.Name : name; 19 | builder.RegisterTypeForNavigation(type, viewName); 20 | } 21 | 22 | /// 23 | /// Registers an object for navigation 24 | /// 25 | /// 26 | /// The type of object to register 27 | /// The unique name to register with the obect. 28 | public static void RegisterTypeForNavigation(this ContainerBuilder builder, Type type, string name) 29 | { 30 | builder.RegisterType(type).Named(name); 31 | } 32 | 33 | /// 34 | /// Registers an object for navigation. 35 | /// 36 | /// The Type of object to register as the view 37 | /// The ViewModel to use as the DataContext for the view 38 | /// The unique name to register with the view 39 | public static void RegisterTypeForNavigation(this ContainerBuilder builder, string name = null) 40 | { 41 | builder.RegisterTypeForNavigationWithViewModel(typeof(TView), name); 42 | } 43 | 44 | private static void RegisterTypeForNavigationWithViewModel(this ContainerBuilder builder, Type viewType, string name) 45 | { 46 | if (string.IsNullOrWhiteSpace(name)) 47 | name = viewType.Name; 48 | 49 | ViewModelLocationProvider.Register(viewType.ToString(), typeof(TViewModel)); 50 | 51 | builder.RegisterTypeForNavigation(viewType, name); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /samples/ModulesSample/Module System Logic/ModuleTrackingState.cs: -------------------------------------------------------------------------------- 1 | using Prism.Avalonia.Infrastructure; 2 | using Prism.Modularity; 3 | using Prism.Mvvm; 4 | 5 | namespace ModulesSample.Module_System_Logic 6 | { 7 | class ModuleTrackingState : BindableBase 8 | { 9 | private string moduleName; 10 | private string configuredDependencies = "(none)"; 11 | private ModuleInitializationStatus moduleInitializationStatus; 12 | private InitializationMode expectedInitializationMode; 13 | private DiscoveryMethod expectedDiscoveryMethod; 14 | 15 | public string ModuleName 16 | { 17 | get { return this.moduleName; } 18 | set 19 | { 20 | if (this.moduleName != value) 21 | { 22 | base.SetProperty(ref this.moduleName, value); 23 | } 24 | } 25 | } 26 | 27 | public ModuleInitializationStatus ModuleInitializationStatus 28 | { 29 | get { return this.moduleInitializationStatus; } 30 | set 31 | { 32 | if (this.moduleInitializationStatus != value) 33 | { 34 | base.SetProperty(ref this.moduleInitializationStatus, value); 35 | } 36 | } 37 | } 38 | 39 | public DiscoveryMethod ExpectedDiscoveryMethod 40 | { 41 | get { return this.expectedDiscoveryMethod; } 42 | set 43 | { 44 | if (this.expectedDiscoveryMethod != value) 45 | { 46 | base.SetProperty(ref this.expectedDiscoveryMethod, value); 47 | } 48 | } 49 | } 50 | 51 | public InitializationMode ExpectedInitializationMode 52 | { 53 | get { return this.expectedInitializationMode; } 54 | set 55 | { 56 | if (this.expectedInitializationMode != value) 57 | { 58 | base.SetProperty(ref this.expectedInitializationMode, value); 59 | } 60 | } 61 | } 62 | 63 | public string ConfiguredDependencies 64 | { 65 | get { return this.configuredDependencies; } 66 | set 67 | { 68 | if (this.configuredDependencies != value) 69 | { 70 | base.SetProperty(ref this.configuredDependencies, value); 71 | } 72 | } 73 | } 74 | } 75 | } -------------------------------------------------------------------------------- /src/Prism.Avalonia/Regions/IRegionNavigationJournal.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace Prism.Regions 7 | { 8 | /// 9 | /// Provides journaling of current, back, and forward navigation within regions. 10 | /// 11 | public interface IRegionNavigationJournal 12 | { 13 | /// 14 | /// Gets a value that indicates whether there is at least one entry in the back navigation history. 15 | /// 16 | /// 17 | /// true if the journal can go back; otherwise, false. 18 | /// 19 | bool CanGoBack { get; } 20 | 21 | /// 22 | /// Gets a value that indicates whether there is at least one entry in the forward navigation history. 23 | /// 24 | /// 25 | /// true if this instance can go forward; otherwise, false. 26 | /// 27 | bool CanGoForward { get; } 28 | 29 | /// 30 | /// Gets the current navigation entry of the content that is currently displayed. 31 | /// 32 | /// The current entry. 33 | IRegionNavigationJournalEntry CurrentEntry {get;} 34 | 35 | /// 36 | /// Gets or sets the target that implements INavigateAsync. 37 | /// 38 | /// The INavigate implementation. 39 | /// 40 | /// This is set by the owner of this journal. 41 | /// 42 | INavigateAsync NavigationTarget { get; set; } 43 | 44 | /// 45 | /// Navigates to the most recent entry in the back navigation history, or does nothing if no entry exists in back navigation. 46 | /// 47 | void GoBack(); 48 | 49 | /// 50 | /// Navigates to the most recent entry in the forward navigation history, or does nothing if no entry exists in forward navigation. 51 | /// 52 | void GoForward(); 53 | 54 | /// 55 | /// Records the navigation to the entry.. 56 | /// 57 | /// The entry to record. 58 | void RecordNavigation(IRegionNavigationJournalEntry entry, bool persistInHistory); 59 | 60 | /// 61 | /// Clears the journal of current, back, and forward navigation histories. 62 | /// 63 | void Clear(); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/Prism.Avalonia/Regions/IRegionCollection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Collections.Specialized; 4 | 5 | namespace Prism.Regions 6 | { 7 | /// 8 | /// Defines a collection of uniquely identified by their Name. 9 | /// 10 | public interface IRegionCollection : IEnumerable, INotifyCollectionChanged 11 | { 12 | /// 13 | /// Gets the IRegion with the name received as index. 14 | /// 15 | /// Name of the region to be retrieved. 16 | /// The identified with the requested name. 17 | IRegion this[string regionName] { get; } 18 | 19 | /// 20 | /// Adds a to the collection. 21 | /// 22 | /// Region to be added to the collection. 23 | void Add(IRegion region); 24 | 25 | /// 26 | /// Removes a from the collection. 27 | /// 28 | /// Name of the region to be removed. 29 | /// if the region was removed from the collection, otherwise . 30 | bool Remove(string regionName); 31 | 32 | /// 33 | /// Checks if the collection contains a with the name received as parameter. 34 | /// 35 | /// The name of the region to look for. 36 | /// if the region is contained in the collection, otherwise . 37 | bool ContainsRegionWithName(string regionName); 38 | 39 | /// 40 | /// Adds a region to the regionmanager with the name received as argument. 41 | /// 42 | /// The name to be given to the region. 43 | /// The region to be added to the regionmanager. 44 | /// Thrown if is . 45 | /// Thrown if and 's name do not match and the is not . 46 | void Add(string regionName, IRegion region); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Prism.Avalonia/Common/ObservableObject.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using Avalonia; 4 | using Avalonia.Controls; 5 | 6 | namespace Prism.Common 7 | { 8 | /// 9 | /// Class that wraps an object, so that other classes can notify for Change events. Typically, this class is set as 10 | /// a Dependency Property on Avalonia.AvaloniaObjects, and allows other classes to observe any changes in the Value. 11 | /// 12 | /// 13 | /// This class is required, because in Silverlight, it's not possible to receive Change notifications for Dependency properties that you do not own. 14 | /// 15 | /// The type of the property that's wrapped in the Observable object 16 | public class ObservableObject : Control, INotifyPropertyChanged 17 | { 18 | /// 19 | /// Identifies the Value property of the ObservableObject 20 | /// 21 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1000:DoNotDeclareStaticMembersOnGenericTypes", Justification = "This is the pattern for WPF dependency properties")] 22 | public static readonly StyledProperty ValueProperty = 23 | AvaloniaProperty.Register(name: nameof(Value)); 24 | 25 | /// 26 | /// Event that gets invoked when the Value property changes. 27 | /// 28 | public event PropertyChangedEventHandler PropertyChanged; 29 | 30 | /// 31 | /// The value that's wrapped inside the ObservableObject. 32 | /// 33 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1721:PropertyNamesShouldNotMatchGetMethods")] 34 | public T Value 35 | { 36 | get { return (T)this.GetValue(ValueProperty); } 37 | set { this.SetValue(ValueProperty, value); } 38 | } 39 | 40 | private static void ValueChangedCallback(AvaloniaObject d, AvaloniaPropertyChangedEventArgs e) 41 | { 42 | ObservableObject thisInstance = ((ObservableObject)d); 43 | PropertyChangedEventHandler eventHandler = thisInstance.PropertyChanged; 44 | if (eventHandler != null) 45 | { 46 | eventHandler(thisInstance, new PropertyChangedEventArgs(nameof(Value))); 47 | } 48 | } 49 | 50 | static ObservableObject() 51 | { 52 | ValueProperty.Changed.Subscribe(args => ValueChangedCallback(args?.Sender, args)); 53 | } 54 | } 55 | } -------------------------------------------------------------------------------- /src/Prism.DryIoc.Avalonia/DryIocExtensions.cs: -------------------------------------------------------------------------------- 1 | using DryIoc; 2 | using Prism.Mvvm; 3 | using System; 4 | 5 | namespace Prism.DryIoc 6 | { 7 | public static class DryIocExtensions 8 | { 9 | /// 10 | /// Registers an object for navigation. 11 | /// 12 | /// The Type of the object to register 13 | /// The unique name to register with the object 14 | public static void RegisterTypeForNavigation(this IContainer container, string name = null) 15 | { 16 | Type type = typeof(T); 17 | string viewName = string.IsNullOrWhiteSpace(name) ? type.Name : name; 18 | container.RegisterTypeForNavigation(type, viewName); 19 | } 20 | 21 | /// 22 | /// Registers an object for navigation 23 | /// 24 | /// 25 | /// The type of object to register 26 | /// The unique name to register with the obect. 27 | public static void RegisterTypeForNavigation(this IContainer container, Type type, string name) 28 | { 29 | container.Register(typeof(object), 30 | type, 31 | made: Made.Of(FactoryMethod.ConstructorWithResolvableArguments), 32 | serviceKey: name); 33 | } 34 | 35 | /// 36 | /// Registers an object for navigation. 37 | /// 38 | /// The Type of object to register as the view 39 | /// The ViewModel to use as the DataContext for the view 40 | /// The unique name to register with the view 41 | /// 42 | public static void RegisterTypeForNavigation(this IContainer container, string name = null) 43 | { 44 | container.RegisterTypeForNavigationWithViewModel(typeof(TView), name); 45 | } 46 | 47 | private static void RegisterTypeForNavigationWithViewModel(this IContainer container, Type viewType, string name = null) 48 | { 49 | if (string.IsNullOrWhiteSpace(name)) 50 | name = viewType.Name; 51 | 52 | ViewModelLocationProvider.Register(viewType.ToString(), typeof(TViewModel)); 53 | 54 | container.RegisterTypeForNavigation(viewType, name); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/Prism.Autofac.Avalonia/Regions/AutofacRegionNavigationContentLoader.cs: -------------------------------------------------------------------------------- 1 | using Autofac; 2 | using Autofac.Core; 3 | using CommonServiceLocator; 4 | using Prism.Regions; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | 9 | namespace Prism.Unity.Regions 10 | { 11 | public class AutofacRegionNavigationContentLoader : RegionNavigationContentLoader 12 | { 13 | private IContainer container; 14 | 15 | public AutofacRegionNavigationContentLoader(IServiceLocator serviceLocator, IContainer container) 16 | : base(serviceLocator) 17 | { 18 | this.container = container; 19 | } 20 | 21 | /// 22 | /// Returns the set of candidates that may satisfiy this navigation request. 23 | /// 24 | /// The region containing items that may satisfy the navigation request. 25 | /// The candidate navigation target. 26 | /// An enumerable of candidate objects from the 27 | protected override IEnumerable GetCandidatesFromRegion(IRegion region, string candidateNavigationContract) 28 | { 29 | if (candidateNavigationContract == null || candidateNavigationContract.Equals(string.Empty)) 30 | throw new ArgumentNullException(nameof(candidateNavigationContract)); 31 | 32 | IEnumerable contractCandidates = base.GetCandidatesFromRegion(region, candidateNavigationContract); 33 | 34 | if (!contractCandidates.Any()) 35 | { 36 | //First try friendly name registration. 37 | var matchingRegistration = container.ComponentRegistry.Registrations.Where(r => r.Services.OfType().Any(s => s.ServiceKey.Equals(candidateNavigationContract))).FirstOrDefault(); 38 | 39 | //If not found, try type registration 40 | if (matchingRegistration == null) 41 | matchingRegistration = container.ComponentRegistry.Registrations.Where(r => candidateNavigationContract.Equals(r.Activator.LimitType.Name, StringComparison.Ordinal)).FirstOrDefault(); 42 | 43 | if (matchingRegistration == null) 44 | return new object[0]; 45 | 46 | string typeCandidateName = matchingRegistration.Activator.LimitType.FullName; 47 | 48 | contractCandidates = base.GetCandidatesFromRegion(region, typeCandidateName); 49 | } 50 | 51 | return contractCandidates; 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/Prism.Avalonia/Modularity/DuplicateModuleException.cs: -------------------------------------------------------------------------------- 1 | 2 | 3 | using System; 4 | 5 | namespace Prism.Modularity 6 | { 7 | /// 8 | /// Exception thrown when a module is declared twice in the same catalog. 9 | /// 10 | public partial class DuplicateModuleException : ModularityException 11 | { 12 | /// 13 | /// Initializes a new instance of the class. 14 | /// 15 | public DuplicateModuleException() 16 | { 17 | } 18 | 19 | /// 20 | /// Initializes a new instance of the class. 21 | /// 22 | /// The exception message. 23 | public DuplicateModuleException(string message) : base(message) 24 | { 25 | } 26 | 27 | /// 28 | /// Initializes a new instance of the class. 29 | /// 30 | /// The exception message. 31 | /// The inner exception. 32 | public DuplicateModuleException(string message, Exception innerException) : base(message, innerException) 33 | { 34 | } 35 | 36 | /// 37 | /// Initializes a new instance of the class with a specified error message. 38 | /// 39 | /// The name of the module. 40 | /// The message that describes the error. 41 | public DuplicateModuleException(string moduleName, string message) 42 | : base(moduleName, message) 43 | { 44 | } 45 | 46 | /// 47 | /// Initializes a new instance of the class with a specified error message and a reference to the inner exception that is the cause of this exception. 48 | /// 49 | /// The name of the module. 50 | /// The error message that explains the reason for the exception. 51 | /// The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. 52 | public DuplicateModuleException(string moduleName, string message, Exception innerException) 53 | : base(moduleName, message, innerException) 54 | { 55 | } 56 | } 57 | } 58 | --------------------------------------------------------------------------------