From f72ee37d03d73e49ba3c0f3ec0b8eef6cb158f97 Mon Sep 17 00:00:00 2001 From: Dan Siegel Date: Sat, 7 May 2022 20:46:28 -0700 Subject: [PATCH 1/6] add missing common namespaces --- src/Prism.Maui/build/Prism.Maui.targets | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Prism.Maui/build/Prism.Maui.targets b/src/Prism.Maui/build/Prism.Maui.targets index 7ef0399..f8a35b1 100644 --- a/src/Prism.Maui/build/Prism.Maui.targets +++ b/src/Prism.Maui/build/Prism.Maui.targets @@ -2,9 +2,13 @@ + + + + \ No newline at end of file From 157cc63ce45c93be42a63ae885170340790d3ba7 Mon Sep 17 00:00:00 2001 From: Dan Siegel Date: Sat, 7 May 2022 21:13:18 -0700 Subject: [PATCH 2/6] Add OnAppStart overloads --- src/Prism.Maui/PrismAppBuilder.cs | 6 +++--- src/Prism.Maui/PrismAppBuilderExtensions.cs | 16 +++++++++++----- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/Prism.Maui/PrismAppBuilder.cs b/src/Prism.Maui/PrismAppBuilder.cs index 378ec40..d668657 100644 --- a/src/Prism.Maui/PrismAppBuilder.cs +++ b/src/Prism.Maui/PrismAppBuilder.cs @@ -25,7 +25,7 @@ public abstract class PrismAppBuilder private List> _registrations { get; } private List> _initializations { get; } private IContainerProvider _container { get; } - private Action _onAppStarted; + private Action _onAppStarted; protected PrismAppBuilder(IContainerExtension containerExtension, MauiAppBuilder builder) { @@ -108,10 +108,10 @@ internal void OnInitialized() prismApp.OnInitialized(); if (_onAppStarted is not null) - _onAppStarted(_container.Resolve()); + _onAppStarted(_container, _container.Resolve()); } - public MauiAppBuilder OnAppStart(Action onAppStarted) + public MauiAppBuilder OnAppStart(Action onAppStarted) { _onAppStarted = onAppStarted; return MauiBuilder; diff --git a/src/Prism.Maui/PrismAppBuilderExtensions.cs b/src/Prism.Maui/PrismAppBuilderExtensions.cs index 358c295..2550485 100644 --- a/src/Prism.Maui/PrismAppBuilderExtensions.cs +++ b/src/Prism.Maui/PrismAppBuilderExtensions.cs @@ -1,9 +1,6 @@ -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Maui; -using Microsoft.Maui.Hosting; -using Prism.Ioc; +using Prism.Ioc; using Prism.Modularity; -using Prism.Mvvm; +using Prism.Navigation; namespace Prism; @@ -43,4 +40,13 @@ public static PrismAppBuilder ConfigureModuleCatalog(this PrismAppBuilder builde configureCatalog(moduleCatalog); }); } + + public static MauiAppBuilder OnAppStart(this PrismAppBuilder builder, Action onAppStarted) => + builder.OnAppStart((_, n) => onAppStarted(n)); + + public static MauiAppBuilder OnAppStart(this PrismAppBuilder builder, Func onAppStarted) => + builder.OnAppStart(async (c, n) => await onAppStarted(c, n)); + + public static MauiAppBuilder OnAppStart(this PrismAppBuilder builder, Func onAppStarted) => + builder.OnAppStart(async (_, n) => await onAppStarted(n)); } From 217c90656ab251e4bb556650e9470cb54a440617 Mon Sep 17 00:00:00 2001 From: Dan Siegel Date: Sat, 7 May 2022 21:20:07 -0700 Subject: [PATCH 3/6] add support for Legacy RegisterTypes in PrismApplication --- src/Prism.Maui/PrismApplication.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Prism.Maui/PrismApplication.cs b/src/Prism.Maui/PrismApplication.cs index ab9f37e..b4c328a 100644 --- a/src/Prism.Maui/PrismApplication.cs +++ b/src/Prism.Maui/PrismApplication.cs @@ -19,6 +19,7 @@ public abstract class PrismApplication : Application, ILegacyPrismApplication protected PrismApplication() { _containerExtension = ContainerLocator.Current; + RegisterTypes(_containerExtension); NavigationService = Container.Resolve((typeof(IApplication), this)); } @@ -27,6 +28,8 @@ protected PrismApplication() // Provided to better support legacy apps updating from Prism.Forms protected virtual void OnInitialized() { } + protected virtual void RegisterTypes(IContainerRegistry containerRegistry) { } + protected sealed override Window CreateWindow(IActivationState activationState) => this.GetDefaultPrismWindow(); } From a84d8525d3193411758455789962c2104f6e54df Mon Sep 17 00:00:00 2001 From: Dan Siegel Date: Sat, 7 May 2022 21:54:30 -0700 Subject: [PATCH 4/6] add default registration for Nav & Tabbed Pages is not registered --- sample/PrismMauiDemo/MauiProgram.cs | 4 +--- src/Prism.Maui/PrismAppBuilder.cs | 5 +++++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/sample/PrismMauiDemo/MauiProgram.cs b/sample/PrismMauiDemo/MauiProgram.cs index 8eaa723..a2209c6 100644 --- a/sample/PrismMauiDemo/MauiProgram.cs +++ b/sample/PrismMauiDemo/MauiProgram.cs @@ -1,4 +1,4 @@ -using MauiModule; +using MauiModule; using Prism; using Prism.Ioc; using Prism.Modularity; @@ -21,8 +21,6 @@ public static MauiApp CreateMauiApp() { containerRegistry.RegisterForNavigation(); containerRegistry.RegisterForNavigation(); - containerRegistry.RegisterForNavigation(); - containerRegistry.RegisterForNavigation(); }) .OnAppStart(async navigationService => { diff --git a/src/Prism.Maui/PrismAppBuilder.cs b/src/Prism.Maui/PrismAppBuilder.cs index d668657..edd4599 100644 --- a/src/Prism.Maui/PrismAppBuilder.cs +++ b/src/Prism.Maui/PrismAppBuilder.cs @@ -104,6 +104,11 @@ internal void OnInitialized() } var app = _container.Resolve(); + if (NavigationRegistry.GetPageType(nameof(NavigationPage)) is null) + ((IContainerRegistry)_container).RegisterForNavigation(); + if (NavigationRegistry.GetPageType(nameof(TabbedPage)) is null) + ((IContainerRegistry)_container).RegisterForNavigation(); + if (app is ILegacyPrismApplication prismApp) prismApp.OnInitialized(); From 6cab7315adf3e56b4a8a293abf8e4724f4bd4816 Mon Sep 17 00:00:00 2001 From: Dan Siegel Date: Sat, 7 May 2022 21:55:31 -0700 Subject: [PATCH 5/6] Add support for Registering views with IServiceCollection --- .../MicrosoftDependencyInjectionExtensions.cs | 28 ++++++++++++++++++- src/Prism.Maui/PrismAppBuilderExtensions.cs | 13 +++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/Prism.Maui/Ioc/MicrosoftDependencyInjectionExtensions.cs b/src/Prism.Maui/Ioc/MicrosoftDependencyInjectionExtensions.cs index 7ed7859..454f48c 100644 --- a/src/Prism.Maui/Ioc/MicrosoftDependencyInjectionExtensions.cs +++ b/src/Prism.Maui/Ioc/MicrosoftDependencyInjectionExtensions.cs @@ -1,4 +1,6 @@ -namespace Prism.Ioc; +using Prism.Navigation; + +namespace Prism.Ioc; public static class MicrosoftDependencyInjectionExtensions { @@ -17,4 +19,28 @@ public static IServiceProvider CreateServiceProvider(this IContainerExtension co return sca.CreateServiceProvider(); } + + public static IServiceCollection RegisterForNavigation(this IServiceCollection services, string name = null) + where TView : Page => + services.RegisterForNavigation(typeof(TView), null, name); + + public static IServiceCollection RegisterForNavigation(this IServiceCollection services, string name = null) + where TView : Page => + services.RegisterForNavigation(typeof(TView), typeof(TViewModel), name); + + public static IServiceCollection RegisterForNavigation(this IServiceCollection services, Type view, Type viewModel, string name = null) + { + if (view is null) + throw new ArgumentNullException(nameof(view)); + + if (string.IsNullOrEmpty(name)) + name = view.Name; + + NavigationRegistry.Register(view, viewModel, name); + services.AddTransient(view); + + if (viewModel != null) + services.AddTransient(viewModel); + return services; + } } diff --git a/src/Prism.Maui/PrismAppBuilderExtensions.cs b/src/Prism.Maui/PrismAppBuilderExtensions.cs index 2550485..10ec24a 100644 --- a/src/Prism.Maui/PrismAppBuilderExtensions.cs +++ b/src/Prism.Maui/PrismAppBuilderExtensions.cs @@ -1,6 +1,7 @@ using Prism.Ioc; using Prism.Modularity; using Prism.Navigation; +using Microsoft.Extensions.Logging; namespace Prism; @@ -49,4 +50,16 @@ public static MauiAppBuilder OnAppStart(this PrismAppBuilder builder, Func onAppStarted) => builder.OnAppStart(async (_, n) => await onAppStarted(n)); + + public static PrismAppBuilder ConfigureServices(this PrismAppBuilder builder, Action configureServices) + { + configureServices(builder.MauiBuilder.Services); + return builder; + } + + public static PrismAppBuilder ConfigureLogging(this PrismAppBuilder builder, Action configureLogging) + { + configureLogging(builder.MauiBuilder.Logging); + return builder; + } } From bf8933454b38975681bb1f4aa572021867d0bd95 Mon Sep 17 00:00:00 2001 From: Dan Siegel Date: Sat, 7 May 2022 22:06:23 -0700 Subject: [PATCH 6/6] Update ReadMe --- README.md | 82 +++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 71 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index cfac92c..2ebd94e 100644 --- a/README.md +++ b/README.md @@ -1,27 +1,87 @@ # Prism.Maui +Prism for .NET MAUI is more than simply a port of Prism for Xamarin.Forms. Many of the features remain largely untouched, however the codebase has been written specifically for MAUI. For existing Prism platforms, PrismApplication is responsible for a lot of service registration. Maui presents a very different paradigm to the app startup process as it uses the AppHostBuilder pattern that you may be familiar with from AspNetCore and other .NET Core applications. Due to the fact that services are registered as part of the MauiAppBuilder bootstrapping, the application bootstrapping that you would typically find as part of the PrismApplication is now instead part of PrismAppBuilder. + +As part of this rewrite, some attention to making it easier for legacy Xamarin.Forms apps to be ported to MAUI has been given. In general however, this has been written with specific attention to the updated application initialization patterns that we see with .NET MAUI. + +## Support + +Please help support Prism and Prism.Maui by becoming a GitHub Sponsor. The work on Prism.Maui is NOT funded by any entity and is done entirely in my spare time. Your financial contributions help support my efforts to provide the best possible experience for the community. + +## Using Prism.Maui + +To help follow MAUI's App Builder pattern we have introduced the `UsePrism` extension on the `MauiAppBuilder`. This will create a `PrismAppBuilder` which gives you specific access to various methods you may want for initializing your application. + ```cs // OOB Maui Application MauiApp.CreateBuilder() .UseMauiApp(); // Prism.Maui -PrismApp.CreateBuilder() - .RegisterServices(containerRegistry => { - containerRegistry.RegisterForNavigation(); - }) - .ConfigureModuleCatalog(catalog => { - catalog.AddModule(); - }) +MauiApp.CreateBuilder() .UsePrismApp(); ``` -## Service Registration +Some of the methods available on the `PrismAppBuilder` are going to seem a bit familiar for developers coming from Prism for Xamarin.Forms such as: + +```cs +MauiApp.CreateBuilder() + .UsePrismApp() + .RegisterServices(container => { + container.Register(); + container.RegisterForNavigation(); + } + .ConfigureModuleCatalog(catalog => { + catalog.AddModule(); + }); + .OnInitialized(() => { + // Do some initializations here + }); +``` + +You will find that this includes useful extensions that consider that you are wiring up these initializations as part of the App Builder. A common case would be where you may have used the container in PrismApplication in the past, you now have an overload that provides the use of the Container. + +```cs +MauiApp.CreateBuilder() + .UsePrismApp() + .OnInitialized(container => { + var foo = container.Resolve(); + // Do some initializations here + }); +``` + +The `PrismAppBuilder` additionally provides some new things to make your life easier. + +```cs +MauiApp.CreateBuilder() + .UsePrismApp() + .OnAppStart(async navigationService => + { + var result = await navigationService.NavigateAsync("MainPage/NavigationPage/ViewA"); + if (!result.Success) + { + System.Diagnostics.Debugger.Break(); + } + }); +``` + +### Microsoft Extensions Support + +To help make it even easier we have added some special extensions to the `PrismAppBuilder` that will make it easier to use Microsoft Extensions. This includes the `ConfigureLogging` method to make it easier to setup your logging while still using the `PrismAppBuilder`. For those who prefer to use `IServiceCollection` to manage their registrations, you can additionally use the `ConfigureServices` extension and bypass the normal Prism `RegisterServices` method. + +```cs +MauiApp.CreateBuilder() + .UsePrismApp() + .ConfigureServices(services => { + services.AddSingleton(); + services.RegisterForNavigation(); + }); +``` -For existing Prism platforms, PrismApplication is responsible for a lot of service registration. Maui presents a very different paradigm to the app startup process as it uses the AppHostBuilder pattern that you may be familiar with from AspNetCore and other .NET Core applications. Due to the fact that services are registered as part of the MauiAppBuilder bootstrapping, the application bootstrapping that you would typically find as part of the PrismApplication is now instead part of PrismAppBuilder. This App Builder provides the typical PrismApplication bootstrapping, while returning the MauiAppBuilder when you call UsePrismApp to allow you to continue to configure your app like any other Maui Application. +## Upgrading from Prism.Forms -For those items such as Pages registered for Navigation which need to be registered with the Prism Container Abstraction, you can register them with the RegisterServices extension off of the PrismAppBuilder. Similarly you can call ConfigureModuleCatalog to register modules or provide delegate to execute as part of the container initialization. Note that these will run prior to the Maui services being registered or the finial container being ready to use. +PrismApplication is largely obsolete for Prism.Maui. The PrismAppBuilder does not have an explicit requirement on it. To make it easier on those who are upgrading, we do have legacy support methods to make updating your existing apps a little easier. This includes a `RegisterTypes` & `OnInitialized` method which will get called during the app initialization. It is recommended however that you migrate this code to your App Builder. ## NOTE -Prism.Maui is current an experimental Alpha. Any preview build is largely meant to solicit additional developer feedback. APIs will likely change and break prior to being merged into the Prism repo and released as a fully official build. \ No newline at end of file +Prism.Maui is current an experimental Alpha. Any preview build is largely meant to solicit additional developer feedback. APIs will likely change and break prior to being merged into the Prism repo and released as a fully official build.