File: MauiContext.cs
Web Access
Project: src\src\Core\src\Core.csproj (Microsoft.Maui)
using System;
using System.Collections.Concurrent;
using Microsoft.Extensions.DependencyInjection;
 
namespace Microsoft.Maui
{
	public class MauiContext : IMauiContext
	{
		readonly WrappedServiceProvider _services;
		readonly Lazy<IMauiHandlersFactory> _handlers;
 
#if ANDROID
		readonly Lazy<Android.Content.Context?> _context;
 
		public Android.Content.Context? Context => _context.Value;
 
		public MauiContext(IServiceProvider services, Android.Content.Context context)
			: this(services)
		{
			AddWeakSpecific(context);
		}
#endif
 
		public MauiContext(IServiceProvider services)
		{
			_ = services ?? throw new ArgumentNullException(nameof(services));
			_services = services is IKeyedServiceProvider
				? new KeyedWrappedServiceProvider(services)
				: new WrappedServiceProvider(services);
 
			_handlers = new Lazy<IMauiHandlersFactory>(() => _services.GetRequiredService<IMauiHandlersFactory>());
#if ANDROID
			_context = new Lazy<Android.Content.Context?>(() => _services.GetService<Android.Content.Context>());
#endif
		}
 
		public IServiceProvider Services => _services;
 
		public IMauiHandlersFactory Handlers => _handlers.Value;
 
		internal void AddSpecific<TService>(TService instance)
			where TService : class
		{
			_services.AddSpecific(typeof(TService), static state => state, instance);
		}
 
		internal void AddWeakSpecific<TService>(TService instance)
			where TService : class
		{
			_services.AddSpecific(typeof(TService), static state => ((WeakReference)state).Target, new WeakReference(instance));
		}
 
		class WrappedServiceProvider : IServiceProvider
		{
			readonly ConcurrentDictionary<Type, (object, Func<object, object?>)> _scopeStatic = new();
 
			public WrappedServiceProvider(IServiceProvider serviceProvider)
			{
				Inner = serviceProvider;
			}
 
			public IServiceProvider Inner { get; }
 
			public object? GetService(Type serviceType)
			{
				if (_scopeStatic.TryGetValue(serviceType, out var scope))
				{
					var (state, getter) = scope;
					return getter.Invoke(state);
				}
 
				return Inner.GetService(serviceType);
			}
 
			public void AddSpecific(Type type, Func<object, object?> getter, object state)
			{
				_scopeStatic[type] = (state, getter);
			}
		}
 
		class KeyedWrappedServiceProvider : WrappedServiceProvider, IKeyedServiceProvider
		{
			public KeyedWrappedServiceProvider(IServiceProvider serviceProvider)
				: base(serviceProvider)
			{
			}
 
			public object? GetKeyedService(Type serviceType, object? serviceKey)
			{
				if (Inner is IKeyedServiceProvider provider)
					return provider.GetKeyedService(serviceType, serviceKey);
 
				// we know this won't work, but we need to call it to throw the right exception
				return Inner.GetRequiredKeyedService(serviceType, serviceKey);
			}
 
			public object GetRequiredKeyedService(Type serviceType, object? serviceKey)
			{
				return Inner.GetRequiredKeyedService(serviceType, serviceKey);
			}
		}
	}
}