Skip to content

Commit

Permalink
remove RegisterForNavigationAttribute provide handler for allowing cu…
Browse files Browse the repository at this point in the history
…stom logic on AutoRegistering Views
  • Loading branch information
dansiegel committed May 25, 2019
1 parent 792bd65 commit 81ea86c
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 74 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,5 @@ namespace Prism.Ioc
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class AutoRegisterForNavigationAttribute : Attribute
{
public bool Automatic { get; set; }
}
}
14 changes: 0 additions & 14 deletions Source/Xamarin/Prism.Forms/Ioc/RegisterForNavigationAttribute.cs

This file was deleted.

69 changes: 12 additions & 57 deletions Source/Xamarin/Prism.Forms/Ioc/TypeAutoLoadExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using Prism.Mvvm;
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
Expand All @@ -9,79 +8,35 @@ namespace Prism.Ioc
{
internal static class IContainerRegistryAutoLoadExtensions
{
public static void AutoRegisterViews(this Type type, IContainerRegistry containerRegistry)
public static void AutoRegisterViews(this Type type, IContainerRegistry containerRegistry, Func<Type, string> getNavigationSegmentName)
{
if (!type.GetCustomAttributes().Any(a => a is AutoRegisterForNavigationAttribute)) return;

var regAttr = type.GetCustomAttribute<AutoRegisterForNavigationAttribute>();
var assembly = type.Assembly;

if (regAttr.Automatic)
{
var viewTypes = assembly.ExportedTypes.Where(t => t.IsSubclassOf(typeof(Page)));
RegisterViewsAutomatically(containerRegistry, viewTypes);
}
else
{
RegisterViewsByAttribute(containerRegistry, assembly);
}
var viewTypes = assembly.ExportedTypes.Where(t => t.IsSubclassOf(typeof(Page)));
RegisterViewsAutomatically(containerRegistry, viewTypes, getNavigationSegmentName);
}

private static void RegisterViewsAutomatically(IContainerRegistry containerRegistry, IEnumerable<Type> viewTypes)
private static void RegisterViewsAutomatically(IContainerRegistry containerRegistry, IEnumerable<Type> viewTypes, Func<Type, string> getNavigationSegmentName)
{
foreach (var viewType in viewTypes)
{
containerRegistry.RegisterForNavigation(viewType, viewType.Name);
}

if (!containerRegistry.IsRegistered<object>(nameof(NavigationPage)))
{
containerRegistry.RegisterForNavigation<NavigationPage>();
RegisterView(containerRegistry, viewType, getNavigationSegmentName);
}

if (!containerRegistry.IsRegistered<object>(nameof(TabbedPage)))
{
containerRegistry.RegisterForNavigation<TabbedPage>();
}
RegisterView(containerRegistry, typeof(NavigationPage), getNavigationSegmentName, true);
RegisterView(containerRegistry, typeof(TabbedPage), getNavigationSegmentName, true);
}

private static void RegisterViewsByAttribute(IContainerRegistry containerRegistry, Assembly assembly)
private static void RegisterView(IContainerRegistry containerRegistry, Type viewType, Func<Type, string> getNavigationSegmentName, bool checkIfRegistered = false)
{
var attrs = assembly.GetCustomAttributes<RegisterForNavigationAttribute>();
foreach (var attr in attrs)
{
RegisterViewByAttribute(containerRegistry, attr);
}

var viewTypes = assembly.ExportedTypes.Where(t => t.IsSubclassOf(typeof(Page))
&& t.GetCustomAttributes<RegisterForNavigationAttribute>().Any());
foreach (var viewType in viewTypes)
{
var attr = viewType.GetCustomAttributes<RegisterForNavigationAttribute>()
.FirstOrDefault(a => a.RuntimePlatform.ToString() == Device.RuntimePlatform || a.RuntimePlatform is null);
attr.ViewType = viewType;
RegisterViewByAttribute(containerRegistry, attr);
}
}

private static void RegisterViewByAttribute(IContainerRegistry containerRegistry, RegisterForNavigationAttribute attr)
{
if (attr.ViewType is null)
throw new Exception($"Cannot auto register View. No ViewType was specified. Name: '{attr.Name}'. ViewModelType: '{attr.ViewModelType?.Name}'");

if (attr.RuntimePlatform != null && attr.RuntimePlatform.ToString() != Device.RuntimePlatform) return;

var name = attr.Name;
if (string.IsNullOrEmpty(name))
{
name = attr.ViewType.Name;
}

containerRegistry.RegisterForNavigation(attr.ViewType, name);
var name = getNavigationSegmentName(viewType);

if (attr.ViewModelType != null)
if(!checkIfRegistered || containerRegistry.IsRegistered<object>(name))
{
ViewModelLocationProvider.Register(attr.ViewType.Name, attr.ViewModelType);
containerRegistry.RegisterForNavigation(viewType, name);
}
}
}
Expand Down
7 changes: 5 additions & 2 deletions Source/Xamarin/Prism.Forms/PrismApplicationBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -124,13 +124,13 @@ protected INavigationService CreateNavigationService(Page page)
/// <summary>
/// Run the bootstrapper process.
/// </summary>
public virtual void Initialize()
protected virtual void Initialize()
{
_containerExtension = CreateContainerExtension();
RegisterRequiredTypes(_containerExtension);
PlatformInitializer?.RegisterTypes(_containerExtension);
RegisterTypes(_containerExtension);
GetType().AutoRegisterViews(_containerExtension);
GetType().AutoRegisterViews(_containerExtension, GetNavigationSegmentNameFromType);
_containerExtension.FinalizeExtension();

if(_setFormsDependencyResolver)
Expand Down Expand Up @@ -166,6 +166,9 @@ protected virtual void SetDependencyResolver(IContainerProvider containerProvide
#endif
}

protected virtual string GetNavigationSegmentNameFromType(Type pageType) =>
pageType.Name;


/// <summary>
/// Creates the container used by Prism.
Expand Down

0 comments on commit 81ea86c

Please sign in to comment.