| 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)}."); } } }