File: HotReload\HotReloadExtensions.cs
Web Access
Project: src\src\Core\src\Core.csproj (Microsoft.Maui)
#nullable enable
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;
using Microsoft.Maui.Hosting;
 
namespace Microsoft.Maui.HotReload
{
	public static class HotReloadExtensions
	{
		public static void CheckHandlers(this IView? view)
		{
			if (view?.Handler == null)
				return;
			//So we can be smart and keep all old handlers
			//However with the Old Legacy Shim layouts, this causes issues.
			//So for now I am just going to kill all handlers, so everything needs rebuilt
			//var handlerType = handlerServiceProvider.GetHandlerType(view.GetType());
			//if (handlerType != view.Handler.GetType()){
			//	view.Handler = null;
			//}
			view.Handler = null;
 
			if (view is IContentView p)
			{
				CheckHandlers(p.PresentedContent);
			}
 
			if (view is IContainer layout)
			{
				foreach (var v in layout)
					CheckHandlers(v);
			}
		}
 
		[RequiresUnreferencedCode("Hot Reload is not trim compatible")]
		public static List<MethodInfo> GetOnHotReloadMethods(this Type type)
		{
			return getOnHotReloadMethods(type).Distinct(new ReflectionMethodComparer()).ToList();
 
			static IEnumerable<MethodInfo> getOnHotReloadMethods(Type type, bool isSubclass = false)
			{
				var flags = BindingFlags.Static | BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.NonPublic;
				if (isSubclass)
					flags = BindingFlags.Static | BindingFlags.NonPublic;
				var foos = type.GetMethods(flags).Where(x => x.GetCustomAttributes(typeof(OnHotReloadAttribute), true).Length > 0).ToList();
				foreach (var foo in foos)
					yield return foo;
 
				if (type.BaseType != null)
					foreach (var foo in getOnHotReloadMethods(type.BaseType, true))
						yield return foo;
			}
		}
 
		class ReflectionMethodComparer : IEqualityComparer<MethodInfo>
		{
			public bool Equals(MethodInfo? g1, MethodInfo? g2) => g1?.MethodHandle == g2?.MethodHandle;
 
			public int GetHashCode(MethodInfo obj) => obj.MethodHandle.GetHashCode();
		}
 
	}
}