Skip to content

Commit 992b188

Browse files
authored
Merge pull request #3042 from PrismLibrary/dev/ds/cleanup
Maui Cleanup
2 parents e7058ca + 23452b5 commit 992b188

File tree

9 files changed

+196
-38
lines changed

9 files changed

+196
-38
lines changed

src/Maui/Prism.Maui/Mvvm/ViewModelLocator.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
namespace Prism.Mvvm;
22

33
/// <summary>
4-
/// This class defines the attached property and related change handler that calls the <see cref="Prism.Mvvm.ViewModelLocationProvider2"/>.
4+
/// This class defines the attached property and related change handler that calls the <see cref="ViewModelLocationProvider"/>.
55
/// </summary>
66
public static class ViewModelLocator
77
{
@@ -60,9 +60,11 @@ internal static void Autowire(object view)
6060
if (view is Element element &&
6161
((ViewModelLocatorBehavior)element.GetValue(AutowireViewModelProperty) == ViewModelLocatorBehavior.Disabled
6262
|| (element.BindingContext is not null && element.BindingContext != element.Parent)))
63+
{
6364
return;
65+
}
6466

65-
else if(view is TabbedPage tabbed)
67+
if (view is TabbedPage tabbed)
6668
{
6769
foreach (var child in tabbed.Children)
6870
Autowire(child);
@@ -75,7 +77,9 @@ internal static void Autowire(object view)
7577
ViewModelLocationProvider.AutoWireViewModelChanged(view, Bind);
7678

7779
if (view is BindableObject bindable && bindable.BindingContext is null)
80+
{
7881
bindable.BindingContext = new object();
82+
}
7983
}
8084

8185
/// <summary>
@@ -86,6 +90,8 @@ internal static void Autowire(object view)
8690
private static void Bind(object view, object viewModel)
8791
{
8892
if (view is BindableObject element)
93+
{
8994
element.BindingContext = viewModel;
95+
}
9096
}
9197
}

src/Maui/Prism.Maui/Mvvm/ViewRegistryBase.cs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
1-
using Prism.Ioc;
2-
using Prism.Navigation.Xaml;
1+
using Prism.Navigation.Xaml;
32

43
namespace Prism.Mvvm;
54

5+
/// <summary>
6+
/// The Base class for .NET Maui's ViewModel Registry
7+
/// </summary>
68
public abstract class ViewRegistryBase : ViewRegistryBase<BindableObject>
79
{
10+
/// <summary>
11+
/// Initializes a new instance of the <see cref="ViewRegistryBase"/>
12+
/// </summary>
13+
/// <param name="registryType">The Registry Type</param>
14+
/// <param name="registrations">The ViewRegistration collection</param>
815
protected ViewRegistryBase(ViewType registryType, IEnumerable<ViewRegistration> registrations)
916
: base(registryType, registrations)
1017
{

src/Maui/Prism.Maui/Navigation/PrismWindowManager.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public Window CreateWindow(Application app, IActivationState activationState)
2020
else if (app.Windows.OfType<PrismWindow>().Any())
2121
return _initialWindow = app.Windows.OfType<PrismWindow>().First();
2222

23-
activationState.Context.Services.GetRequiredService<PrismAppBuilder>().OnAppStarted();
23+
activationState.Context.Services.GetRequiredService<PrismAppBuilder>().OnCreateWindow();
2424

2525
return _initialWindow ?? throw new InvalidNavigationException("Expected Navigation Failed. No Root Window has been created.");
2626
}

src/Maui/Prism.Maui/Navigation/Xaml/Navigation.cs

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
using System.ComponentModel;
22
using Prism.Common;
3-
using Prism.Ioc;
43
using Prism.Navigation.Internals;
54

65
namespace Prism.Navigation.Xaml;
@@ -79,13 +78,19 @@ private static void OnNavigationScopeChanged(BindableObject bindable, object old
7978
/// <param name="value">The Can Navigate value</param>
8079
public static void SetCanNavigate(BindableObject view, bool value) => view.SetValue(CanNavigateProperty, value);
8180

81+
/// <summary>
82+
/// Gets the Child Regions for a given <see cref="Page"/>
83+
/// </summary>
84+
/// <param name="page">The <see cref="Page"/> host.</param>
85+
/// <param name="setIfNull">Initializes the <see cref="ChildRegionCollection"/> if it has not been set.</param>
86+
/// <returns>The <see cref="ChildRegionCollection"/>.</returns>
8287
[EditorBrowsable(EditorBrowsableState.Never)]
8388
public static ChildRegionCollection GetChildRegions(this Page page, bool setIfNull = false)
8489
{
8590
var value = page.GetValue(ChildMvvmViewsProperty) as ChildRegionCollection;
8691
if (value is null && setIfNull)
8792
{
88-
value = new ChildRegionCollection();
93+
value = [];
8994
page.SetValue(ChildMvvmViewsProperty, value);
9095
}
9196

@@ -111,18 +116,31 @@ internal static void ClearChildRegions(this Page page)
111116
[EditorBrowsable(EditorBrowsableState.Never)]
112117
public static INavigationService GetNavigationService(Page page)
113118
{
114-
if (page == null) throw new ArgumentNullException(nameof(page));
119+
ArgumentNullException.ThrowIfNull(page);
115120

116121
var container = page.GetContainerProvider();
117122
return container.Resolve<INavigationService>();
118123
}
119124

125+
/// <summary>
126+
/// Sets the <see cref="IContainerProvider"/> for the given <see cref="BindableObject"/>
127+
/// </summary>
128+
/// <param name="bindable">The <see cref="BindableObject"/>.</param>
129+
/// <param name="container">The <see cref="IContainerProvider"/>.</param>
120130
[EditorBrowsable(EditorBrowsableState.Never)]
121131
public static void SetContainerProvider(this BindableObject bindable, IContainerProvider container)
122132
{
123133
bindable.SetValue(NavigationScopeProperty, container);
124134
}
125135

136+
/// <summary>
137+
/// Gets the Container for the given View
138+
/// </summary>
139+
/// <param name="bindable">The View</param>
140+
/// <returns>The <see cref="IContainerProvider"/>.</returns>
141+
/// <remarks>
142+
/// Will initialize a new Container Scope if the <see cref="Mvvm.ViewModelLocatorBehavior"/> is Forced.
143+
/// </remarks>
126144
[EditorBrowsable(EditorBrowsableState.Never)]
127145
public static IContainerProvider GetContainerProvider(this BindableObject bindable)
128146
{

src/Maui/Prism.Maui/PrismAppBuilder.cs

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public sealed class PrismAppBuilder
2121
private List<Action<IContainerRegistry>> _registrations { get; }
2222
private List<Action<IContainerProvider>> _initializations { get; }
2323
private IContainerProvider _container { get; }
24-
private Func<IContainerProvider, INavigationService, Task> _onAppStarted;
24+
private Func<IContainerProvider, INavigationService, Task> _createWindow;
2525
private Action<RegionAdapterMappings> _configureAdapters;
2626
private Action<IRegionBehaviorFactory> _configureBehaviors;
2727

@@ -106,12 +106,16 @@ internal static object DefaultViewModelLocator(object view, Type viewModelType)
106106
{
107107
try
108108
{
109-
if (view is not BindableObject bindable)
109+
if (view is not BindableObject bindable || bindable.BindingContext is not null)
110110
return null;
111111

112112
var container = bindable.GetContainerProvider();
113113

114-
return container.Resolve(viewModelType);
114+
return container.Resolve(viewModelType, (typeof(IDispatcher), bindable.Dispatcher));
115+
}
116+
catch (ViewModelCreationException)
117+
{
118+
throw;
115119
}
116120
catch (Exception ex)
117121
{
@@ -177,26 +181,26 @@ internal void OnInitialized()
177181
}
178182
}
179183

180-
internal void OnAppStarted()
184+
internal void OnCreateWindow()
181185
{
182-
if (_onAppStarted is null)
183-
throw new ArgumentException("You must call OnAppStart on the PrismAppBuilder.");
186+
if (_createWindow is null)
187+
throw new ArgumentException("You must call CreateWindow on the PrismAppBuilder.");
184188

185189
// Ensure that this is executed before we navigate.
186190
OnInitialized();
187-
var onStart = _onAppStarted(_container, _container.Resolve<INavigationService>());
191+
var onStart = _createWindow(_container, _container.Resolve<INavigationService>());
188192
onStart.Wait();
189193
}
190194

191195
/// <summary>
192196
/// When the <see cref="Application"/> is started and the native platform calls <see cref="IApplication.CreateWindow(IActivationState?)"/>
193197
/// this delegate will be invoked to do your initial Navigation.
194198
/// </summary>
195-
/// <param name="onAppStarted">The Navigation Delegate.</param>
199+
/// <param name="createWindow">The Navigation Delegate.</param>
196200
/// <returns>The <see cref="PrismAppBuilder"/>.</returns>
197-
public PrismAppBuilder CreateWindow(Func<IContainerProvider, INavigationService, Task> onAppStarted)
201+
public PrismAppBuilder CreateWindow(Func<IContainerProvider, INavigationService, Task> createWindow)
198202
{
199-
_onAppStarted = onAppStarted;
203+
_createWindow = createWindow;
200204
return this;
201205
}
202206

src/Maui/Prism.Maui/PrismAppBuilderExtensions.cs

Lines changed: 87 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,33 @@
66

77
namespace Prism;
88

9+
/// <summary>
10+
/// Common extensions and overloads for the <see cref="PrismAppBuilder"/>
11+
/// </summary>
912
public static class PrismAppBuilderExtensions
1013
{
1114
private static bool s_didRegisterModules = false;
1215

16+
/// <summary>
17+
/// Configures the <see cref="MauiAppBuilder"/> to use Prism with a callback for the <see cref="PrismAppBuilder"/>
18+
/// </summary>
19+
/// <param name="builder">The <see cref="MauiAppBuilder"/>.</param>
20+
/// <param name="containerExtension">The instance of the <see cref="IContainerExtension"/> Prism should use.</param>
21+
/// <param name="configurePrism">A delegate callback for the <see cref="PrismAppBuilder"/></param>
22+
/// <returns>The <see cref="MauiAppBuilder"/>.</returns>
1323
public static MauiAppBuilder UsePrism(this MauiAppBuilder builder, IContainerExtension containerExtension, Action<PrismAppBuilder> configurePrism)
1424
{
1525
var prismBuilder = new PrismAppBuilder(containerExtension, builder);
1626
configurePrism(prismBuilder);
1727
return builder;
1828
}
1929

30+
/// <summary>
31+
/// Provides a Delegate to invoke when the App is initialized.
32+
/// </summary>
33+
/// <param name="builder">The <see cref="PrismAppBuilder"/>.</param>
34+
/// <param name="action">The delegate to invoke.</param>
35+
/// <returns>The <see cref="PrismAppBuilder"/>.</returns>
2036
public static PrismAppBuilder OnInitialized(this PrismAppBuilder builder, Action action)
2137
{
2238
return builder.OnInitialized(_ => action());
@@ -45,9 +61,24 @@ public static PrismAppBuilder ConfigureModuleCatalog(this PrismAppBuilder builde
4561
});
4662
}
4763

64+
/// <summary>
65+
/// When the <see cref="Application"/> is started and the native platform calls <see cref="IApplication.CreateWindow(IActivationState?)"/>
66+
/// this delegate will be invoked to do your initial Navigation.
67+
/// </summary>
68+
/// <param name="builder">The <see cref="PrismAppBuilder"/>.</param>
69+
/// <param name="uri">The initial Navigation Uri.</param>
70+
/// <returns>The <see cref="PrismAppBuilder"/>.</returns>
4871
public static PrismAppBuilder CreateWindow(this PrismAppBuilder builder, string uri) =>
4972
builder.CreateWindow(navigation => navigation.NavigateAsync(uri));
5073

74+
/// <summary>
75+
/// When the <see cref="Application"/> is started and the native platform calls <see cref="IApplication.CreateWindow(IActivationState?)"/>
76+
/// this delegate will be invoked to do your initial Navigation.
77+
/// </summary>
78+
/// <param name="builder">The <see cref="PrismAppBuilder"/>.</param>
79+
/// <param name="uri">The intial Navigation Uri.</param>
80+
/// <param name="onError">A delegate callback if the navigation fails.</param>
81+
/// <returns>The <see cref="PrismAppBuilder"/>.</returns>
5182
public static PrismAppBuilder CreateWindow(this PrismAppBuilder builder, string uri, Action<Exception> onError) =>
5283
builder.CreateWindow(async navigation =>
5384
{
@@ -56,30 +87,78 @@ public static PrismAppBuilder CreateWindow(this PrismAppBuilder builder, string
5687
onError(result.Exception);
5788
});
5889

59-
public static PrismAppBuilder CreateWindow(this PrismAppBuilder builder, Func<IContainerProvider, INavigationService, Task> CreateWindowed) =>
60-
builder.CreateWindow((c, n) => CreateWindowed(c, n));
90+
/// <summary>
91+
/// When the <see cref="Application"/> is started and the native platform calls <see cref="IApplication.CreateWindow(IActivationState?)"/>
92+
/// this delegate will be invoked to do your initial Navigation.
93+
/// </summary>
94+
/// <param name="builder">The <see cref="PrismAppBuilder"/>.</param>
95+
/// <param name="createWindow">The Navigation Delegate.</param>
96+
/// <returns>The <see cref="PrismAppBuilder"/>.</returns>
97+
public static PrismAppBuilder CreateWindow(this PrismAppBuilder builder, Func<IContainerProvider, INavigationService, Task> createWindow) =>
98+
builder.CreateWindow((c, n) => createWindow(c, n));
6199

62-
public static PrismAppBuilder CreateWindow(this PrismAppBuilder builder, Func<INavigationService, Task> CreateWindowed) =>
63-
builder.CreateWindow((_, n) => CreateWindowed(n));
100+
/// <summary>
101+
/// When the <see cref="Application"/> is started and the native platform calls <see cref="IApplication.CreateWindow(IActivationState?)"/>
102+
/// this delegate will be invoked to do your initial Navigation.
103+
/// </summary>
104+
/// <param name="builder">The <see cref="PrismAppBuilder"/>.</param>
105+
/// <param name="createWindow">The Navigation Delegate.</param>
106+
/// <returns>The <see cref="PrismAppBuilder"/>.</returns>
107+
public static PrismAppBuilder CreateWindow(this PrismAppBuilder builder, Func<INavigationService, Task> createWindow) =>
108+
builder.CreateWindow((_, n) => createWindow(n));
64109

65-
public static PrismAppBuilder CreateWindow(this PrismAppBuilder builder, Func<INavigationService, INavigationBuilder> CreateWindowed) =>
66-
builder.CreateWindow(n => CreateWindowed(n).NavigateAsync());
110+
/// <summary>
111+
/// When the <see cref="Application"/> is started and the native platform calls <see cref="IApplication.CreateWindow(IActivationState?)"/>
112+
/// this delegate will be invoked to do your initial Navigation.
113+
/// </summary>
114+
/// <param name="builder">The <see cref="PrismAppBuilder"/>.</param>
115+
/// <param name="createWindow">The Navigation Delegate.</param>
116+
/// <returns>The <see cref="PrismAppBuilder"/>.</returns>
117+
public static PrismAppBuilder CreateWindow(this PrismAppBuilder builder, Func<INavigationService, INavigationBuilder> createWindow) =>
118+
builder.CreateWindow(n => createWindow(n).NavigateAsync());
119+
120+
/// <summary>
121+
/// When the <see cref="Application"/> is started and the native platform calls <see cref="IApplication.CreateWindow(IActivationState?)"/>
122+
/// this delegate will be invoked to do your initial Navigation.
123+
/// </summary>
124+
/// <param name="builder">The <see cref="PrismAppBuilder"/>.</param>
125+
/// <param name="createWindow">The Navigation Delegate.</param>
126+
/// <returns>The <see cref="PrismAppBuilder"/>.</returns>
127+
public static PrismAppBuilder CreateWindow(this PrismAppBuilder builder, Func<IContainerProvider, INavigationService, INavigationBuilder> createWindow) =>
128+
builder.CreateWindow((c, n) => createWindow(c, n).NavigateAsync());
67129

68-
public static PrismAppBuilder CreateWindow(this PrismAppBuilder builder, Func<IContainerProvider, INavigationService, INavigationBuilder> CreateWindowed) =>
69-
builder.CreateWindow((c, n) => CreateWindowed(c, n).NavigateAsync());
70130

131+
/// <summary>
132+
/// Provides a configuration delegate to add services to the <see cref="MauiAppBuilder.Services"/>
133+
/// </summary>
134+
/// <param name="builder">The <see cref="PrismAppBuilder"/>.</param>
135+
/// <param name="configureServices">Configuration Delegate</param>
136+
/// <returns>The <see cref="PrismAppBuilder"/>.</returns>
71137
public static PrismAppBuilder ConfigureServices(this PrismAppBuilder builder, Action<IServiceCollection> configureServices)
72138
{
73139
configureServices(builder.MauiBuilder.Services);
74140
return builder;
75141
}
76142

143+
/// <summary>
144+
/// Provides a delegate to configure Logging within the Maui application
145+
/// </summary>
146+
/// <param name="builder">The <see cref="PrismAppBuilder"/>.</param>
147+
/// <param name="configureLogging"></param>
148+
/// <returns>The <see cref="PrismAppBuilder"/>.</returns>
77149
public static PrismAppBuilder ConfigureLogging(this PrismAppBuilder builder, Action<ILoggingBuilder> configureLogging)
78150
{
79151
configureLogging(builder.MauiBuilder.Logging);
80152
return builder;
81153
}
82154

155+
/// <summary>
156+
/// Provides a configuration Delegate to the <see cref="ViewModelLocationProvider"/> to set the
157+
/// DefaultViewTypeToViewModelTypeResolver.
158+
/// </summary>
159+
/// <param name="builder">The <see cref="PrismAppBuilder"/>.</param>
160+
/// <param name="viewModelTypeResolver">The Configuration Delegate for the Default ViewType to ViewModelType Resolver.</param>
161+
/// <returns>The <see cref="PrismAppBuilder"/>.</returns>
83162
public static PrismAppBuilder ConfigureViewTypeToViewModelTypeResolver(this PrismAppBuilder builder, Func<Type, Type> viewModelTypeResolver)
84163
{
85164
ViewModelLocationProvider.SetDefaultViewTypeToViewModelTypeResolver(viewModelTypeResolver);

src/Prism.Core/Mvvm/ViewRegistryBase{TBaseView}.cs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,21 +28,15 @@ public object CreateView(IContainerProvider container, string name)
2828
{
2929
try
3030
{
31-
var registration = GetRegistration(name);
32-
if (registration is null)
33-
throw new KeyNotFoundException($"No view with the name '{name}' has been registered");
34-
31+
var registration = GetRegistration(name) ?? throw new KeyNotFoundException($"No view with the name '{name}' has been registered");
3532
var view = container.Resolve(registration.View) as TBaseView;
3633
SetNavigationNameProperty(view, registration.Name);
37-
//;
3834

39-
//;
4035
SetContainerProvider(view, container);
4136
ConfigureView(view, container);
4237

4338
if (registration.ViewModel is not null)
4439
SetViewModelProperty(view, registration.ViewModel);
45-
//
4640

4741
Autowire(view);
4842

0 commit comments

Comments
 (0)