File: TypeDiscoveryService.cs
Web Access
Project: src\src\System.Windows.Forms\tests\IntegrationTests\DesignSurface\DesignSurfaceExt\DesignSurfaceExt.csproj (DesignSurfaceExt)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Immutable;
using System.Reflection;
 
namespace System.ComponentModel.Design;
 
/// <summary>
///  This service is requested by <see cref="TypeDescriptor" /> when asking for type information for a component.
///  This is a sample implementation suitable for this sample application.
/// </summary>
internal sealed class TypeDiscoveryService : ITypeDiscoveryService
{
    public TypeDiscoveryService() { }
 
    private readonly ConcurrentDictionary<Type, ImmutableArray<Type>> _discoveredTypesCache = new();
 
    public ICollection GetTypes(Type baseType, bool excludeGlobalTypes)
    {
        return baseType is null
            ? throw new ArgumentNullException(nameof(baseType))
            : (ICollection)_discoveredTypesCache.GetOrAdd(baseType, type => FindTypes(type, AppDomain.CurrentDomain.GetAssemblies()));
 
        static ImmutableArray<Type> FindTypes(Type baseType, Assembly[] assemblies)
        {
            var builder = ImmutableArray.CreateBuilder<Type>();
 
            foreach (var assembly in assemblies)
            {
                Type[] types;
                try
                {
                    types = assembly.GetTypes();
                }
                catch (ReflectionTypeLoadException exception)
                {
                    types = exception.Types!;
                }
 
                foreach (var type in types)
                {
                    if (baseType.IsAssignableFrom(type))
                    {
                        builder.Add(type);
                    }
                }
            }
 
            return builder.ToImmutable();
        }
    }
}