File: Hosting\Internal\MauiFactory.cs
Web Access
Project: src\src\Core\src\Core.csproj (Microsoft.Maui)
#nullable enable
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using Microsoft.Extensions.DependencyInjection;
 
namespace Microsoft.Maui.Hosting.Internal
{
	class MauiFactory : IMauiFactory
	{
		readonly IMauiServiceCollection _collection;
 
		protected IMauiServiceCollection InternalCollection => _collection;
 
		// TODO: do this properly and support scopes
		readonly ConcurrentDictionary<ServiceDescriptor, object?> _singletons;
 
		public MauiFactory(IMauiServiceCollection collection)
		{
			_collection = collection ?? throw new ArgumentNullException(nameof(collection));
			_singletons = new ConcurrentDictionary<ServiceDescriptor, object?>();
 
			// to make things easier, just add the provider
			collection.AddSingleton<IServiceProvider>(this);
		}
 
		public object? GetService(Type serviceType)
		{
			if (serviceType == null)
				throw new ArgumentNullException(nameof(serviceType));
 
			if (!_collection.TryGetService(serviceType, out ServiceDescriptor? descriptor) || descriptor == null)
				return null;
 
			if (descriptor.Lifetime == ServiceLifetime.Singleton)
			{
				if (_singletons.TryGetValue(descriptor, out var singletonInstance))
					return singletonInstance;
			}
 
			var typeInstance = CreateInstance(descriptor);
			if (descriptor.Lifetime == ServiceLifetime.Singleton)
			{
				_singletons[descriptor] = typeInstance;
			}
			return typeInstance;
		}
 
		object? CreateInstance(ServiceDescriptor item)
		{
			if (item.ImplementationType != null)
			{
				return Activator.CreateInstance(item.ImplementationType);
			}
 
			if (item.ImplementationInstance != null)
				return item.ImplementationInstance;
 
			if (item.ImplementationFactory != null)
				return item.ImplementationFactory(this);
 
			throw new InvalidOperationException($"You need to provide an {nameof(item.ImplementationType)}, an {nameof(item.ImplementationFactory)} or an {nameof(item.ImplementationInstance)}.");
		}
	}
}