using System.Collections; namespace Spectre.Console.Testing; /// /// A fake type resolver suitable for testing. /// public sealed class FakeTypeResolver : ITypeResolver { private readonly Dictionary> _registrations; private readonly Dictionary> _instances; /// /// Initializes a new instance of the class. /// /// The registrations. /// The singleton registrations. public FakeTypeResolver( Dictionary> registrations, Dictionary> instances) { _registrations = registrations ?? throw new ArgumentNullException(nameof(registrations)); _instances = instances ?? throw new ArgumentNullException(nameof(instances)); } /// public object? Resolve(Type? type) { if (type == null) { return null; } if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IEnumerable<>)) { // return all registrations type = type.GenericTypeArguments[0]; var allRegistrations = Activator.CreateInstance(typeof(List<>).MakeGenericType(type)); var castList = allRegistrations as IList; if (_instances.TryGetValue(type, out var listInstances)) { listInstances.ForEach(i => castList.Add(i)); } if (_registrations.TryGetValue(type, out var listRegistrations)) { listRegistrations .Select(x => Activator.CreateInstance(x)!) .ToList() .ForEach(i => castList.Add(i)); } return allRegistrations; } if (_instances.TryGetValue(type, out var instances)) { return instances.LastOrDefault(); } if (_registrations.TryGetValue(type, out var registrations)) { // The type might be an interface, but the registration should be a class. // So call CreateInstance on the first registration rather than the type. return registrations.Count == 0 ? null : Activator.CreateInstance(registrations.Last()); } return null; } }