File: Hosting\MauiHandlersCollectionExtensions.cs
Web Access
Project: src\src\Core\src\Core.csproj (Microsoft.Maui)
using System;
using System.Diagnostics.CodeAnalysis;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Maui.Hosting.Internal;
 
namespace Microsoft.Maui.Hosting
{
	public static partial class MauiHandlersCollectionExtensions
	{
		/// <summary>
		/// Registers a handler with the underlying service container via AddTransient.
		/// </summary>
		/// <param name="handlersCollection">The element collection</param>
		/// <param name="viewType">The type of view to register</param>
		/// <param name="handlerType">The handler type that represents the element</param>
		/// <returns>The handler collection</returns>
		public static IMauiHandlersCollection AddHandler(
			this IMauiHandlersCollection handlersCollection,
			Type viewType,
			[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type handlerType)
		{
			if (!typeof(IElement).IsAssignableFrom(viewType) || !typeof(IElementHandler).IsAssignableFrom(handlerType))
				throw new InvalidOperationException($"Unable to add handler mapping for {viewType} and {handlerType}. Please ensure that {viewType} implements {nameof(IElement)} and {handlerType} implements {nameof(IElementHandler)}.");
 
			handlersCollection.RegisterHandlerServiceType(viewType);
#pragma warning disable RS0030 // Do not use banned APIs, the current method is also banned
			handlersCollection.AddTransient(viewType, handlerType);
#pragma warning restore RS0030 // Do not use banned APIs
			return handlersCollection;
		}
 
		/// <summary>
		/// Registers a handler with the underlying service container via AddTransient.
		/// </summary>
		/// <typeparam name="TType">The type of element to register</typeparam>
		/// <typeparam name="TTypeRender">The handler type that represents the element</typeparam>
		/// <param name="handlersCollection">The handler collection</param>
		/// <returns>The handler collection</returns>
		public static IMauiHandlersCollection AddHandler<TType, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TTypeRender>(
			this IMauiHandlersCollection handlersCollection)
			where TType : IElement
			where TTypeRender : IElementHandler
		{
			handlersCollection.RegisterHandlerServiceType(typeof(TType));
#pragma warning disable RS0030 // Do not use banned APIs, the current method is also banned
			handlersCollection.AddTransient(typeof(TType), typeof(TTypeRender));
#pragma warning restore RS0030 // Do not use banned APIs
			return handlersCollection;
		}
 
		/// <summary>
		/// Registers a handler with the underlying service container via AddTransient.
		/// </summary>
		/// <typeparam name="TType">The type of element to register</typeparam>
		/// <param name="handlersCollection">The handler collection</param>
		/// <param name="handlerImplementationFactory">A factory method to create the handler</param>
		/// <returns>The handler collection</returns>
		public static IMauiHandlersCollection AddHandler<TType>(
			this IMauiHandlersCollection handlersCollection,
			Func<IServiceProvider, IElementHandler> handlerImplementationFactory)
			where TType : IElement
		{
			handlersCollection.RegisterHandlerServiceType(typeof(TType));
			handlersCollection.AddTransient(typeof(TType), handlerImplementationFactory);
			return handlersCollection;
		}
 
		/// <summary>
		/// Registers a handler with the underlying service container via AddTransient.
		/// </summary>
		/// <param name="handlersCollection">The handler collection</param>
		/// <param name="viewType">The type of element to register</param>
		/// <param name="handlerType">The handler type that represents the element</param>
		/// <returns>The handler collection</returns>
		public static IMauiHandlersCollection TryAddHandler(
			this IMauiHandlersCollection handlersCollection,
			Type viewType,
			[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type handlerType)
		{
			if (!typeof(IElement).IsAssignableFrom(viewType) || !typeof(IElementHandler).IsAssignableFrom(handlerType))
				throw new InvalidOperationException($"Unable to add handler mapping for {viewType} and {handlerType}. Please ensure that {viewType} implements {nameof(IElement)} and {handlerType} implements {nameof(IElementHandler)}.");
 
			handlersCollection.RegisterHandlerServiceType(viewType);
#pragma warning disable RS0030 // Do not use banned APIs, the current method is also banned
			handlersCollection.TryAddTransient(viewType, handlerType);
#pragma warning restore RS0030 // Do not use banned APIs
			return handlersCollection;
		}
 
		/// <summary>
		/// Registers a handler with the underlying service container via AddTransient.
		/// </summary>
		/// <typeparam name="TType">The type of element to register</typeparam>
		/// <typeparam name="TTypeRender">The handler type that represents the element</typeparam>
		/// <param name="handlersCollection">The handler collection</param>
		/// <returns>The handler collection</returns>
		public static IMauiHandlersCollection TryAddHandler<TType, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TTypeRender>(
			this IMauiHandlersCollection handlersCollection)
			where TType : IView
			where TTypeRender : IViewHandler
		{
			handlersCollection.RegisterHandlerServiceType(typeof(TType));
#pragma warning disable RS0030 // Do not use banned APIs, the current method is also banned
			handlersCollection.TryAddTransient(typeof(TType), typeof(TTypeRender));
#pragma warning restore RS0030 // Do not use banned APIs
			return handlersCollection;
		}
 
		/// <summary>
		/// Registers a handler with the underlying service container via AddTransient.
		/// </summary>
		/// <typeparam name="TType">The type of element to register</typeparam>
		/// <param name="handlersCollection">The handler collection</param>
		/// <param name="handlerImplementationFactory">A factory method to create the handler</param>
		/// <returns>The handler collection</returns>
		public static IMauiHandlersCollection TryAddHandler<TType>(
			this IMauiHandlersCollection handlersCollection,
			Func<IServiceProvider, IElementHandler> handlerImplementationFactory)
			where TType : IElement
		{
			handlersCollection.RegisterHandlerServiceType(typeof(TType));
			handlersCollection.TryAddTransient(typeof(TType), handlerImplementationFactory);
			return handlersCollection;
		}
 
		private static void RegisterHandlerServiceType(this IMauiHandlersCollection handlersCollection, Type virtualViewType)
		{
			RegisteredHandlerServiceTypeSet.GetInstance(handlersCollection).Add(virtualViewType);
		}
	}
}