-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
Move ViewRegistry to Prism.Core
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
using Prism.Common; | ||
using Prism.Mvvm; | ||
using Prism.Services; | ||
|
||
namespace Prism.Ioc; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
using Prism.Common; | ||
using Prism.Mvvm; | ||
|
||
namespace Prism.Ioc; | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
using Prism.Common; | ||
using Prism.Mvvm; | ||
|
||
namespace Prism.Ioc; | ||
|
||
|
This file was deleted.
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,154 +1,35 @@ | ||
using System.Text.RegularExpressions; | ||
using System.Xml.Linq; | ||
using Prism.Common; | ||
using Prism.Ioc; | ||
using Prism.Ioc; | ||
using Prism.Navigation.Xaml; | ||
|
||
namespace Prism.Mvvm; | ||
|
||
public abstract class ViewRegistryBase : IViewRegistry | ||
public abstract class ViewRegistryBase : ViewRegistryBase<BindableObject> | ||
{ | ||
private readonly IEnumerable<ViewRegistration> _registrations; | ||
private readonly ViewType _registryType; | ||
|
||
protected ViewRegistryBase(ViewType registryType, IEnumerable<ViewRegistration> registrations) | ||
: base(registryType, registrations) | ||
{ | ||
_registrations = registrations; | ||
_registryType = registryType; | ||
} | ||
|
||
public IEnumerable<ViewRegistration> Registrations => | ||
_registrations.Where(x => x.Type == _registryType); | ||
|
||
public Type GetViewType(string name) => | ||
GetRegistration(name)?.View; | ||
|
||
public object CreateView(IContainerProvider container, string name) | ||
protected override void Autowire(BindableObject view) | ||
{ | ||
try | ||
{ | ||
var registration = GetRegistration(name); | ||
if (registration is null) | ||
throw new KeyNotFoundException($"No view with the name '{name}' has been registered"); | ||
|
||
var view = container.Resolve(registration.View) as BindableObject; | ||
view.SetValue(ViewModelLocator.NavigationNameProperty, registration.Name); | ||
|
||
view.SetContainerProvider(container); | ||
ConfigureView(view, container); | ||
|
||
if (registration.ViewModel is not null) | ||
view.SetValue(ViewModelLocator.ViewModelProperty, registration.ViewModel); | ||
|
||
Autowire(view); | ||
if (view.BindingContext is not null) | ||
return; | ||
|
||
return view; | ||
} | ||
catch (KeyNotFoundException) | ||
{ | ||
throw; | ||
} | ||
catch (ViewModelCreationException) | ||
{ | ||
throw; | ||
} | ||
catch (Exception ex) | ||
{ | ||
throw new ViewCreationException(name, _registryType, ex); | ||
} | ||
ViewModelLocator.Autowire(view); | ||
} | ||
|
||
private IEnumerable<Type> GetCandidates(Type viewModelType) | ||
protected override void SetContainerProvider(BindableObject view, IContainerProvider container) | ||
{ | ||
var names = new List<string> | ||
{ | ||
Regex.Replace(viewModelType.Name, @"ViewModel$", string.Empty), | ||
Regex.Replace(viewModelType.Name, @"Model$", string.Empty), | ||
}; | ||
|
||
if (_registryType == ViewType.Page) | ||
names.Add(Regex.Replace(viewModelType.Name, @"ViewModel$", "Page")); | ||
else if (_registryType == ViewType.Region) | ||
names.Add(Regex.Replace(viewModelType.Name, @"ViewModel$", "Region")); | ||
else if (_registryType == ViewType.Dialog) | ||
names.Add(Regex.Replace(viewModelType.Name, @"ViewModel$", "Dialog")); | ||
|
||
names = names.Where(x => !x.EndsWith("PagePage")).ToList(); | ||
|
||
var namespaces = _registryType switch | ||
{ | ||
ViewType.Page => new[] | ||
{ | ||
viewModelType.Namespace.Replace("ViewModels", "Views"), | ||
viewModelType.Namespace.Replace("ViewModels", "Pages") | ||
}, | ||
ViewType.Region => new[] | ||
{ | ||
viewModelType.Namespace.Replace("ViewModels", "Views"), | ||
viewModelType.Namespace.Replace("ViewModels", "Regions") | ||
}, | ||
ViewType.Dialog => new[] | ||
{ | ||
viewModelType.Namespace.Replace("ViewModels", "Views"), | ||
viewModelType.Namespace.Replace("ViewModels", "Dialogs") | ||
}, | ||
_ => new[] | ||
{ | ||
viewModelType.Namespace.Replace("ViewModels", "Views"), | ||
} | ||
}; | ||
|
||
var candidates = namespaces.Select(@namespace => names.Select(name => $"{@namespace}.{name}")) | ||
.SelectMany(x => x) | ||
.Select(x => viewModelType.AssemblyQualifiedName.Replace(viewModelType.FullName, x)); | ||
return candidates | ||
.Select(x => Type.GetType(x, false)) | ||
.Where(x => x is not null); | ||
view.SetContainerProvider(container); | ||
} | ||
|
||
public string GetViewModelNavigationKey(Type viewModelType) | ||
protected override void SetNavigationNameProperty(BindableObject view, string name) | ||
{ | ||
var registration = Registrations.LastOrDefault(x => x.ViewModel == viewModelType); | ||
if (registration is not null) | ||
return registration.Name; | ||
|
||
var candidates = GetCandidates(viewModelType); | ||
registration = Registrations.LastOrDefault(x => candidates.Any(c => c == x.View)); | ||
if (registration is not null) | ||
{ | ||
return registration.Name; | ||
} | ||
|
||
throw new KeyNotFoundException($"No View with the ViewModel '{viewModelType.Name}' has been registered"); | ||
view.SetValue(ViewModelLocator.NavigationNameProperty, name); | ||
} | ||
|
||
public IEnumerable<ViewRegistration> ViewsOfType(Type baseType) => | ||
Registrations.Where(x => x.View == baseType || x.View.IsAssignableTo(baseType)); | ||
|
||
public bool IsRegistered(string name) => | ||
GetRegistration(name) is not null; | ||
|
||
protected ViewRegistration GetRegistration(string name) => | ||
Registrations.LastOrDefault(x => x.Name == name); | ||
|
||
protected abstract void ConfigureView(BindableObject bindable, IContainerProvider container); | ||
|
||
protected void Autowire(BindableObject view) | ||
protected override void SetViewModelProperty(BindableObject view, Type viewModelType) | ||
{ | ||
if (view.BindingContext is not null) | ||
return; | ||
|
||
ViewModelLocator.Autowire(view); | ||
view.SetValue(ViewModelLocator.ViewModelProperty, viewModelType); | ||
} | ||
|
||
//public static Type GetPageType(string name) | ||
//{ | ||
// var registrations = _registrations.Where(x => x.Name == name); | ||
// if (!registrations.Any()) | ||
// throw new KeyNotFoundException(name); | ||
// if (registrations.Count() > 1) | ||
// throw new InvalidOperationException(string.Format(Resources.MultipleViewsRegisteredForNavigationKey, name, string.Join(", ", registrations.Select(x => x.View.FullName)))); | ||
|
||
// return registrations.First().View; | ||
//} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,4 @@ | ||
using Prism.Common; | ||
using Prism.Ioc; | ||
using Prism.Ioc; | ||
using Prism.Mvvm; | ||
|
||
namespace Prism.Regions; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,5 @@ | ||
using Prism.Ioc; | ||
using Prism.Mvvm; | ||
using Prism.Common; | ||
|
||
namespace Prism.Services; | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using Prism.Ioc; | ||
|
||
namespace Prism.Mvvm; | ||
|
||
/// <summary> | ||
/// Provides an abstraction layer for ViewRegistration that can be mocked | ||
/// </summary> | ||
public interface IViewRegistry | ||
{ | ||
/// <summary> | ||
/// The existing ViewRegistrations | ||
/// </summary> | ||
IEnumerable<ViewRegistration> Registrations { get; } | ||
|
||
/// <summary> | ||
/// Creates a view given a specified instance of the Container and a navigation name | ||
/// </summary> | ||
/// <param name="container"></param> | ||
/// <param name="name"></param> | ||
/// <returns></returns> | ||
object CreateView(IContainerProvider container, string name); | ||
|
||
/// <summary> | ||
/// Gets the ViewType for a specified navigation name | ||
/// </summary> | ||
/// <param name="name"></param> | ||
/// <returns></returns> | ||
Type GetViewType(string name); | ||
|
||
/// <summary> | ||
/// Gets the navigation name for a specified ViewModelType | ||
/// </summary> | ||
/// <param name="viewModelType"></param> | ||
/// <returns></returns> | ||
string GetViewModelNavigationKey(Type viewModelType); | ||
|
||
/// <summary> | ||
/// Gets the Registrations where the View is of a given base type | ||
/// </summary> | ||
/// <param name="baseType"></param> | ||
/// <returns></returns> | ||
IEnumerable<ViewRegistration> ViewsOfType(Type baseType); | ||
|
||
/// <summary> | ||
/// Confirms whether the given navigation name has been registered | ||
/// </summary> | ||
/// <param name="name"></param> | ||
/// <returns></returns> | ||
bool IsRegistered(string name); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
using Prism.Common; | ||
using System; | ||
|
||
namespace Prism.Mvvm; | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
using System; | ||
using System.ComponentModel; | ||
|
||
namespace Prism.Mvvm; | ||
|
||
public class ViewModelCreationException : Exception | ||
Check warning on line 6 in src/Prism.Core/Mvvm/ViewModelCreationException.cs GitHub Actions / build-prism-maui / Build Prism.Maui
Check warning on line 6 in src/Prism.Core/Mvvm/ViewModelCreationException.cs GitHub Actions / build-prism-core / Build Prism.Core
Check warning on line 6 in src/Prism.Core/Mvvm/ViewModelCreationException.cs GitHub Actions / build-prism-uno / Build Prism.Uno
|
||
{ | ||
private static Func<object, string> _viewNameDelegate = null; | ||
private static string GetViewName(object view) => _viewNameDelegate is null ? "Platform not initialized" : _viewNameDelegate(view); | ||
|
||
[EditorBrowsable(EditorBrowsableState.Never)] | ||
public static void SetViewNameDelegate(Func<object, string> viewNameDelegate) => _viewNameDelegate = viewNameDelegate; | ||
Check warning on line 12 in src/Prism.Core/Mvvm/ViewModelCreationException.cs GitHub Actions / build-prism-maui / Build Prism.Maui
Check warning on line 12 in src/Prism.Core/Mvvm/ViewModelCreationException.cs GitHub Actions / build-prism-core / Build Prism.Core
Check warning on line 12 in src/Prism.Core/Mvvm/ViewModelCreationException.cs GitHub Actions / build-prism-uno / Build Prism.Uno
|
||
|
||
public ViewModelCreationException(object view, Exception innerException) | ||
Check warning on line 14 in src/Prism.Core/Mvvm/ViewModelCreationException.cs GitHub Actions / build-prism-maui / Build Prism.Maui
Check warning on line 14 in src/Prism.Core/Mvvm/ViewModelCreationException.cs GitHub Actions / build-prism-core / Build Prism.Core
Check warning on line 14 in src/Prism.Core/Mvvm/ViewModelCreationException.cs GitHub Actions / build-prism-uno / Build Prism.Uno
|
||
: base($"Unable to Create ViewModel for '{view.GetType().FullName}'.", innerException) | ||
{ | ||
View = view; | ||
ViewName = GetViewName(view); | ||
} | ||
|
||
public string ViewName { get; } | ||
|
||
public object View { get; } | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,6 @@ | ||
namespace Prism.Common; | ||
using System; | ||
|
||
namespace Prism.Mvvm; | ||
|
||
public record ViewRegistration | ||
{ | ||
|